package com.park.service.impl;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.util.SystemOutLogger;
import org.apache.struts.chain.commands.servlet.CreateAction;
import org.apache.velocity.tools.config.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.redis.core.types.RedisClientInfo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mysql.jdbc.Util;
import com.park.dao.CarportStatusDetailDAO;
import com.park.dao.MonthuserDAO;
import com.park.dao.PosChargeDataDAO;
import com.park.dao.PosdataDAO;
import com.park.model.CarportStatusDetail;
import com.park.model.ChargedataParkWithTable;
import com.park.model.Constants;
import com.park.model.FeeCriterion;
import com.park.model.Feecriteriontopark;
import com.park.model.Monthuser;
import com.park.model.Monthuserconsumerrecord;
import com.park.model.Outsideparkinfo;
import com.park.model.Park;
import com.park.model.ParkRecordData;
import com.park.model.Parkcarauthority;
import com.park.model.Parknoticeauthority;
import com.park.model.Parktoalipark;
import com.park.model.PosChargeData;
import com.park.model.Posdata;
import com.park.model.posdataReceive;
import com.park.service.ActiveMqService;
import com.park.service.AliParkFeeService;
import com.park.service.ChargeDataService;
import com.park.service.FeeCriterionService;
import com.park.service.FeecriterionToParkService;
import com.park.service.JedisClient;
import com.park.service.JsonUtils;
import com.park.service.MonthUserService;
import com.park.service.MonthuserConsumerRecordService;
import com.park.service.OutsideParkInfoService;
import com.park.service.ParkCarAuthorityService;
import com.park.service.ParkNoticeAuthorityService;
import com.park.service.ParkService;
import com.park.service.ParkToAliparkService;
import com.park.service.PosChargeDataService;
import com.park.service.Utility;

import antlr.Lookahead;

@Service
public class PosChargeDataServiceImpl implements PosChargeDataService {

	@Autowired
	MonthUserService monthUserService;
	@Autowired
	PosChargeDataDAO chargeDao;

	@Autowired
	ParkService parkService;

	@Autowired
	FormatTime formatTime;
	@Autowired
	private MonthuserDAO monthUserDao;

	@Autowired
	private CarportStatusDetailDAO carportStatusDetailDAO;
	@Autowired
	ParkNoticeAuthorityService parkNoticeAuthorityService;

	@Autowired
	FeeCriterionService criterionService;

	@Autowired
	FeecriterionToParkService feecriterionToParkService;

	@Autowired
	private OutsideParkInfoService outsideParkInfoService;

	@Autowired
	ChargeDataService chargedataService;

	@Autowired
	AliParkFeeService aliparkFeeService;
	@Autowired
	ParkToAliparkService parkToAliparkService;
	@Autowired
	MonthuserConsumerRecordService monthuserConsumerService;

	@Autowired
	ActiveMqService ActiveMqService;

	@Resource(name = "jedisClient")
	private JedisClient jedisClient;

	private static final Log logger = LogFactory.getLog(PosChargeDataServiceImpl.class);

	DecimalFormat df = new DecimalFormat(".00");

	@Override
	public PosChargeData getById(int id) {
		return chargeDao.getById(id);
	}

	@Override
	public List<PosChargeData> get() {
		return chargeDao.get();
	}

	@Override
	public List<PosChargeData> getUnCompleted() {
		return chargeDao.getUnCompleted();
	}

	@Override
	public List<PosChargeData> getPage(int low, int count) {
		return chargeDao.getPage(low, count);
	}

	@Override
	public int count() {
		return chargeDao.count();
	}

	@Override
	public int insert(PosChargeData item) {

		Parknoticeauthority parknoticeauthority = parkNoticeAuthorityService.getByParkId(item.getParkId()).get(0);
		if (parknoticeauthority != null && parknoticeauthority.getWeixin() == true) {
			Map<String, String> argstoali = new HashMap<>();
			argstoali.put("parkName", item.getParkDesc());
			argstoali.put("carNumber", item.getCardNumber());
			argstoali.put("enterTime", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
			ActiveMqService.SendWithQueueName(JsonUtils.objectToJson(argstoali), "weixinEnterInfo");
		}
		Park park = parkService.getParkById(item.getParkId());
		int num = chargeDao.insert(item);
		// 在插入之后 要不获取不到id
		if (ArrayUtils.contains(Constants.parkToQuene, item.getParkId()) || park.getDescription().contains("工行停车场")) {
			logger.info(item.getCardNumber() + "进入工行停车场,发送队列");
			PosChargeData tmPosChargeData = item;
			tmPosChargeData.setExitDate1(tmPosChargeData.getEntranceDate());
			String str = JsonUtils.objectToJson(tmPosChargeData);
			item.setExitDate1(null);

			try {
				ActiveMqService.SendPosChargeData(str);
			} catch (Exception e) {
				// TODO: handle exception
				logger.info(item.getCardNumber() + "发送工行队列异常" + e.getLocalizedMessage());
			}

		}
		if (num == 1) {
			logger.info(item.getCardNumber() + "进入" + park.getName() + "前车位数" + park.getPortLeftCount());
			int leftPort = (park.getPortLeftCount() - 1) >= 0 ? (park.getPortLeftCount() - 1) : 0;
			parkService.updateLeftPortCount(park.getId(), leftPort);
			logger.info(item.getCardNumber() + "进入" + park.getName() + "后车位数" + leftPort);
		}
		return num;
	}

	@Override
	public int update(PosChargeData item) {
		return chargeDao.update(item);
	}

	@Override
	public List<PosChargeData> getCharges(String cardNumber) throws Exception {

		String poschargeId = jedisClient.get("query" + cardNumber);
		List<PosChargeData> charges = new ArrayList<>();
		if (poschargeId != null) {
			logger.info(cardNumber + "query得到-" + poschargeId);
			charges.add(chargeDao.getById(Integer.parseInt(poschargeId)));

		} else {
			charges = chargeDao.getDebt(cardNumber);
		}

		// List<PosChargeData> charges = chargeDao.getDebt(cardNumber);

		for (PosChargeData tmpcharge : charges) {

			if (tmpcharge.getExitDate() == null) {
				this.calExpense(tmpcharge, new Date(), false);

			}
		}
		return charges;
	}

	@Override
	public List<PosChargeData> getDebt(String cardNumber) throws Exception {
		// System.out.println("获取poschargedata list前: "+new
		// Date().getTime()+"\n");
		List<PosChargeData> charges = chargeDao.getDebt(cardNumber);

		// System.out.println("获取poschargedata list后: "+new
		// Date().getTime()+"\n");
		List<PosChargeData> tmPosChargeDatas = new ArrayList<>();
		// System.out.println("poschargedata list录入支付宝前: "+new
		// Date().getTime()+"\n");

		for (PosChargeData charge : charges) {
			if (charge.getExitDate() == null) {
				// 信息录入支付宝
				List<Parktoalipark> parktoaliparks = parkToAliparkService.getByParkId(charge.getParkId());
				try {
					if (!parktoaliparks.isEmpty()) {
						Parktoalipark parktoalipark = parktoaliparks.get(0);
						Map<String, String> argstoali = new HashMap<>();
						argstoali.put("parking_id", parktoalipark.getAliparkingid());
						argstoali.put("car_number", cardNumber);
						argstoali.put("out_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
						ActiveMqService.SendWithQueueName(JsonUtils.objectToJson(argstoali), "aliExitInfo");
						// aliparkFeeService.parkingExitinfoSync(argstoali);
					}
					List<Parknoticeauthority> parkcarauthorities = parkNoticeAuthorityService
							.getByParkId(charge.getParkId());
					if (!parkcarauthorities.isEmpty() && (parkcarauthorities.get(0)).getAlipay() == true) {
						Map<String, String> argstoali = new HashMap<>();
						argstoali.put("parking_id", "PI1501317472942184881");
						argstoali.put("car_number", cardNumber);
						argstoali.put("out_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
						ActiveMqService.SendWithQueueName(JsonUtils.objectToJson(argstoali), "aliExitInfo");
					}

				} catch (Exception e) {
					// TODO: handle exception
				}

				tmPosChargeDatas.add(charge);
			}
		}
		// System.out.println("poschargedata list录入支付宝后: "+new
		// Date().getTime()+"\n");
		// System.out.println("poschargedata 计算前: "+new Date().getTime()+"\n");
		for (PosChargeData tmpcharge : tmPosChargeDatas) {
			this.calExpense(tmpcharge, new Date(), false);
		}
		int tmpint = 0;
		for (PosChargeData tmpcharge : tmPosChargeDatas) {
			tmpint++;
			if (tmpint > 1) {
				tmpcharge.setChargeMoney(0);
				tmpcharge.setPaidCompleted(true);
				tmpcharge.setPaidMoney(0);
				tmpcharge.setExitDate1(tmpcharge.getEntranceDate());
				tmpcharge.setRejectReason("平台清场");
				update(tmpcharge);
			}
		}
		// System.out.println("poschargedata 计算后: "+new Date().getTime()+"\n");
		return tmPosChargeDatas;
	}

	@Override
	public List<PosChargeData> getLastRecord(String carNumber, int count) {
		return chargeDao.getLastRecord(carNumber, count);
	}

	@Override
	public List<PosChargeData> getLastRecordUpdateInTime(int parkId, String carNumber, int count) {
		return chargeDao.getLastRecordUpdateInTime(parkId, carNumber, count);
	}

	@Override
	public PosChargeData payWithOperatorId(String cardNumber, double money, String operatorId) throws Exception {
		double theMoney = money;
		List<PosChargeData> charges = new ArrayList<>();

		charges = chargeDao.getDebt(cardNumber);
		PosChargeData lastCharge = charges.get(0);
		lastCharge.setPaidMoney(theMoney);
		lastCharge.setChargeMoney(theMoney);// 将本地计费金额更新到服务器，取消服务器计费
		lastCharge.setPaidCompleted(true);
		lastCharge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
		lastCharge.setOperatorId(operatorId);
		lastCharge.setExitDate1(new Date());
		this.update(lastCharge);
		// jedisClient.del("query"+cardNumber);
		return lastCharge;
	}

	@Override
	public PosChargeData pay(String cardNumber, double money) throws Exception {
		double theMoney = money;
		synchronized (this) {
			List<PosChargeData> charges = this.getCharges(cardNumber);
			int count = charges.size();
			PosChargeData lastCharge = charges.get(0);

			lastCharge.setPaidMoney(theMoney);
			lastCharge.setChargeMoney(theMoney);// 将本地计费金额更新到服务器，取消服务器计费
			lastCharge.setPaidCompleted(true);
			lastCharge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
			lastCharge.setExitDate1(new Date());
			this.update(lastCharge);
			// jedisClient.del("P-"+lastCharge.getParkId()+"-"+cardNumber);
			jedisClient.del("query" + cardNumber);
			return lastCharge;
		}
	}

	@Override
	public void calExpenseMulti(PosChargeData charge, Date exitDate, Boolean isQuery, Boolean isMultiFeeCtriterion,
			int carType) throws Exception {

		Boolean isMonthUser = false;
		Boolean isRealMonthUser = false;
		// Boolean isMonthUserMoreCars=false;
		List<Monthuser> monthusers = monthUserService.getByCarnumberAndPark(charge.getCardNumber(), charge.getParkId());
		Monthuser monthuserUse = new Monthuser();
		for (Monthuser monthuser : monthusers) {
			if (monthuser.getType() == 0) {
				Long diff = (monthuser.getEndtime().getTime() - (new Date()).getTime());
				if (diff > 0) {
					isMonthUser = true;
					monthuserUse = monthuser;
					isRealMonthUser = true;
					break;
				}
			}
		}
		Park park = parkService.getParkById(charge.getParkId());
		Boolean isMultiCarsOneCarport = false;
		if (park.getDescription() != null && park.getDescription().contains("一位多车")) {
			isMultiCarsOneCarport = true;
		}

		if (isMultiCarsOneCarport && isRealMonthUser && monthuserUse.getPlatecolor() != null
				&& monthuserUse.getPlatecolor().equals("包月转为临停")) {
			isRealMonthUser = false;
			monthuserUse.setPlatecolor("出场完结");
			monthUserService.updateByPrimaryKeySelective(monthuserUse);
		}
		if (isMultiCarsOneCarport && isRealMonthUser && monthuserUse.getPlatecolor() != null
				&& monthuserUse.getPlatecolor().equals("临停恢复为包月")) {
			isRealMonthUser = false;
			List<Monthuser> monthuserss = monthUserService.getByParkAndPort(monthuserUse.getParkid(),
					monthuserUse.getCardnumber());

			for (Monthuser monthuser : monthuserss) {
				if (isMultiCarsOneCarport && isRealMonthUser && monthuserUse.getPlatecolor() != null
						&& monthuser.getPlatecolor().contains("包月出场")) {
					String[] datas = monthuser.getPlatecolor().split("#");
					try {
						Date dateout = new SimpleDateFormat(Constants.DATEFORMAT).parse(datas[1]);
						charge.setExitDate1(dateout);// 更改出场时间为原先包月车的出场时间
						exitDate = dateout;
						charge.setRejectReason("临停转包月");
					} catch (Exception e) {
						// TODO: handle exception
					}
					monthuser.setPlatecolor("出场完结");
					monthUserService.updateByPrimaryKeySelective(monthuser);
					monthuserUse.setPlatecolor("出场完结");
					for (Monthuser strMonthUser : monthuserss) {
						if (strMonthUser.getPlatecolor().contains("包月转为临停")) {
							monthuserUse.setPlatecolor(
									"包月出场#" + new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
							strMonthUser.setPlatecolor("临停恢复为包月");
							monthUserService.updateByPrimaryKeySelective(strMonthUser);
							break;
						}
					}
					monthUserService.updateByPrimaryKeySelective(monthuserUse);
					break;
				}
			}

		}
		if (isRealMonthUser) {
			charge.setChargeMoney(0);
			charge.setUnPaidMoney(0);
			charge.setExitDate1(exitDate);
			charge.setPaidCompleted(true);
			charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
			if (!isQuery) {
				if (isMultiCarsOneCarport && monthuserUse.getPlatecolor().equals("多车包月入场")) {
					monthuserUse.setPlatecolor("出场完结");
					List<Monthuser> monthuserss = monthUserService.getByUsernameAndPark(monthuserUse.getOwner(),
							monthuserUse.getParkid());
					for (Monthuser monthuser : monthuserss) {
						if (monthuser.getPlatecolor().equals("包月转为临停")) {
							monthuser.setPlatecolor("临停恢复为包月");
							monthuserUse.setPlatecolor(
									"包月出场#" + new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
							monthUserService.updateByPrimaryKeySelective(monthuser);
							break;
						}
					}
					monthUserService.updateByPrimaryKeySelective(monthuserUse);
				}
				this.update(charge);
			}
			return;
		}

		Integer criterionId = park.getFeeCriterionId();
		FeeCriterion criterion = criterionService.getById(criterionId);

		if (criterion.getType() == 2) {
			newFeeCalcExpense2(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}
		if (criterion.getType() == 1) {
			newFeeCalcExpense1(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}

		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(charge.getEntranceDate());
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "07";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		int isOneTimeExpense = charge.getIsOneTimeExpense();
		if (charge.getIsLargeCar() == false) {
			Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
			for (String name : dates.keySet()) {
				charge.setEntranceDate(name);
				int houra = Integer.parseInt(name.substring(11, 13));
				int hourNight = Integer.parseInt(nightStartHour);
				int hourDay = Integer.parseInt(nightEndHour);
				boolean isNight = false;
				if (houra > 12) {
					if (houra >= hourNight) {
						isNight = true;
					}
				} else {
					if (houra < hourDay) {
						isNight = true;
					}
				}
				if (isNight) {
					charge.setIsOneTimeExpense(1);
					this.calExpenseSmallCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				} else if (isOneTimeExpense == 0) {
					charge.setIsOneTimeExpense(0);
					this.calExpenseSmallCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				} else {
					charge.setIsOneTimeExpense(1);
					this.calExpenseSmallCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				}
			}
			// System.out.println("计费计算后: "+new Date().getTime()+"\n");
			// System.out.println("计费更新前: "+new Date().getTime()+"\n");
			charge.setEntranceDate(startTime);
			charge.setExitDate(endTime);
			if (charge.getPaidMoney() >= charge.getChargeMoney() && !isQuery) {
				charge.setUnPaidMoney(0);
				charge.setPaidCompleted(true);
				charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));

				charge.setChangeMoney(charge.getPaidMoney() - charge.getChargeMoney());
			} else {
				charge.setUnPaidMoney(charge.getChargeMoney() - charge.getPaidMoney());
			}
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			// System.out.println("计费更新后: "+new Date().getTime()+"\n");

		} else {
			Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
			for (String name : dates.keySet()) {
				charge.setEntranceDate(name);
				int houra = Integer.parseInt(name.substring(11, 13));
				int hourNight = Integer.parseInt(nightStartHour);
				int hourDay = Integer.parseInt(nightEndHour);
				boolean isNight = false;
				if (houra > 12) {
					if (houra >= hourNight) {
						isNight = true;
					}
				} else {
					if (houra < hourDay) {
						isNight = true;
					}
				}
				if (isNight) {
					charge.setIsOneTimeExpense(1);
					this.calExpenseLargeCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				} else if (isOneTimeExpense == 0) {
					charge.setIsOneTimeExpense(0);
					this.calExpenseLargeCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				} else {
					charge.setIsOneTimeExpense(1);
					this.calExpenseLargeCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				}
			}
			charge.setEntranceDate(startTime);
			charge.setExitDate(endTime);
			if (charge.getPaidMoney() >= charge.getChargeMoney() && !isQuery) {
				charge.setUnPaidMoney(0);
				charge.setPaidCompleted(true);
				charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
				charge.setChangeMoney(charge.getPaidMoney() - charge.getChargeMoney());
			} else {
				charge.setUnPaidMoney(charge.getChargeMoney() - charge.getPaidMoney());
			}
			if (isRealMonthUser) {
				// charge.setPaidMoney(0);
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}

		}

	}

	@Override
	public List<PosChargeData> getDebt(String cardNumber, Date exitDate) throws Exception {
		// TODO Auto-generated method stub
		String poschargeId = jedisClient.get("query" + cardNumber);
		List<PosChargeData> charges = new ArrayList<>();
		if (poschargeId != null) {
			logger.info(cardNumber + "query得到-" + poschargeId);
			charges.add(chargeDao.getById(Integer.parseInt(poschargeId)));
			// if (charges.get(0).isPaidCompleted()) {
			// charges.clear();
			// return charges;
			// }
		} else {
			charges = chargeDao.getDebt(cardNumber);
		}
		List<PosChargeData> tmPosChargeDatas = new ArrayList<>();
		for (PosChargeData charge : charges) {
			// 信息录入支付宝
			if (charge.getExitDate() == null) {
				List<Parktoalipark> parktoaliparks = parkToAliparkService.getByParkId(charge.getParkId());
				try {
					if (!parktoaliparks.isEmpty()) {
						Parktoalipark parktoalipark = parktoaliparks.get(0);
						Map<String, String> argstoali = new HashMap<>();
						argstoali.put("parking_id", parktoalipark.getAliparkingid());
						argstoali.put("car_number", cardNumber);
						argstoali.put("out_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(exitDate));
						ActiveMqService.SendWithQueueName(JsonUtils.objectToJson(argstoali), "aliExitInfo");
					}
					List<Parknoticeauthority> parkcarauthorities = parkNoticeAuthorityService
							.getByParkId(charge.getParkId());
					if (!parkcarauthorities.isEmpty() && (parkcarauthorities.get(0)).getAlipay() == true) {
						Map<String, String> argstoali = new HashMap<>();
						argstoali.put("parking_id", "PI1501317472942184881");
						argstoali.put("car_number", cardNumber);
						argstoali.put("out_time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
						ActiveMqService.SendWithQueueName(JsonUtils.objectToJson(argstoali), "aliExitInfo");
					}
				} catch (Exception e) {
					// TODO: handle exception
				}
				if (charge.getChargeMoney() == 0) {
					charge.setPaidCompleted(true);
					charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
					update(charge);
				}
				tmPosChargeDatas.add(charge);
			}
		}
		for (PosChargeData tmpcharge : tmPosChargeDatas) {
			Park park = parkService.getParkById(tmpcharge.getParkId());
			if (park.getType() == 1) {
				this.calExpenseType1(tmpcharge, exitDate, false);
			} else {
				this.calExpense(tmpcharge, exitDate, false);
			}

		}
		int tmpint = 0;
		// for (PosChargeData tmpcharge : tmPosChargeDatas) {
		// tmpint++;
		// if (tmpint > 1) {
		// tmpcharge.setChargeMoney(0);
		// tmpcharge.setRejectReason("平台清场");
		// update(tmpcharge);
		// }
		// }
		return tmPosChargeDatas;
	}

	@Override
	public void calExpenseLargeCar(PosChargeData charge, Date exitDate, Boolean isQuery) throws Exception {
		Park park = parkService.getParkById(charge.getParkId());

		Integer criterionId = park.getFeeCriterionId();

		if (criterionId == null)
			throw new Exception("no fee criterion");
		FeeCriterion criterion = criterionService.getById(criterionId);
		if (criterion.getIsonetimeexpense() != null && criterion.getIsonetimeexpense().intValue() == 1) {
			charge.setIsOneTimeExpense(1);
		}
		charge.setExitDate1(exitDate);
		double expense = 0;
		float diffMin = (charge.getExitDate().getTime() - charge.getEntranceDate().getTime()) / (1000 * 60f);
		if (charge.getIsOneTimeExpense() == 1 && diffMin >= criterion.getFreemins()) {
			expense = criterion.getOnetimeexpense();
		} else {
			float firstHour = criterion.getStep1capacity();
			if (diffMin > criterion.getFreemins()) {
				if (diffMin <= firstHour) {
					double intervals = Math
							.ceil((diffMin - criterion.getFreemins()) / criterion.getTimeoutpriceinterval());
					expense = intervals * criterion.getStep1pricelarge();
				} else {
					double intervals1 = Math
							.ceil((firstHour - criterion.getFreemins()) / criterion.getTimeoutpriceinterval());
					expense = intervals1 * criterion.getStep1pricelarge();
					double intervals2 = Math.ceil((diffMin - firstHour) / (criterion.getTimeoutpriceinterval()));
					// double intervals2 = Math.ceil((diffMin - firstHour) /
					// (criterion.getTimeoutpriceinterval()/2));

					expense += intervals2 * criterion.getStep2pricelarge();
				}
			}
		}

		charge.setChargeMoney(Double.valueOf(df.format(expense + charge.getChargeMoney())));
		if (charge.getChargeMoney() > (criterion.getMaxexpense() * 2)) {
			charge.setChargeMoney(criterion.getMaxexpense() * 2);
		}
	}

	@Override
	public void calExpenseSmallCar(PosChargeData charge, Date exitDate, Boolean isQuery) throws Exception {

		Park park = parkService.getParkById(charge.getParkId());

		Integer criterionId = park.getFeeCriterionId();

		if (criterionId == null)
			throw new Exception("no fee criterion");

		FeeCriterion criterion = criterionService.getById(criterionId);

		charge.setExitDate1(exitDate);
		double expense = 0;
		if (criterion.getIsonetimeexpense() != null && criterion.getIsonetimeexpense().intValue() == 1) {
			charge.setIsOneTimeExpense(1);
		}
		float diffMin = (float) Math
				.ceil((charge.getExitDate().getTime() - charge.getEntranceDate().getTime()) / (1000 * 60f));
		if (charge.getIsOneTimeExpense() == 1 && diffMin >= criterion.getFreemins()) {
			expense = criterion.getOnetimeexpense();
		} else {

			float firstHour = criterion.getStep1capacity();

			if (diffMin > criterion.getFreemins()) {
				if (diffMin <= firstHour) {
					double intervals = Math
							.ceil((diffMin - criterion.getFreemins()) / (float) criterion.getTimeoutpriceinterval());
					expense = intervals * criterion.getStep1price();
				} else {
					double intervals1 = Math
							.ceil((firstHour - criterion.getFreemins()) / (float) criterion.getTimeoutpriceinterval());
					expense = intervals1 * criterion.getStep1price();
					double intervals2 = Math
							.ceil((diffMin - firstHour) / (float) (criterion.getTimeoutpriceinterval()));
					// double intervals2 = Math.ceil((diffMin - firstHour) /
					// (criterion.getTimeoutpriceinterval()/2));
					expense += intervals2 * criterion.getStep2price();
				}
			}
		}
		if (expense > criterion.getMaxexpense()) {
			// charge.setChargeMoney(criterion.getMaxexpense());
			expense = criterion.getMaxexpense();
		}

		charge.setChargeMoney(Double.valueOf(df.format(expense + charge.getChargeMoney())));

	}

	@Override
	public List<PosChargeData> queryDebt(String cardNumber, Date exitDate) throws Exception {
		// TODO Auto-generated method stub
		logger.info("[query]参数:" + cardNumber + exitDate);
		String poschargeId = jedisClient.get("query" + cardNumber);
		List<PosChargeData> charges = new ArrayList<>();
		if (poschargeId != null) {
			logger.info(cardNumber + "query得到" + poschargeId);
			charges.add(chargeDao.getById(Integer.parseInt(poschargeId)));
			if (charges.get(0).isPaidCompleted()) {
				charges.clear();
				return charges;
			}
		} else {
			charges = chargeDao.getDebt(cardNumber);
			logger.info(charges);
		}

		for (PosChargeData charge : charges) {
			if (charge.getExitDate() == null) {
				Park park = parkService.getParkById(charge.getParkId());
				if (park.getType() == 1) {
					this.calExpenseType1(charge, exitDate, true);
				} else {
//					this.calExpense(charge, exitDate, true);
					List<Monthuser> monthusers = monthUserService.getByCarnumberAndPark(charge.getCardNumber(),
							charge.getParkId());
					// Park park = parkService.getParkById(charge.getParkId());
					FeeCriterion feeCriterion = criterionService.getById(park.getFeeCriterionId());
					if (park.getDescription() != null && park.getDescription().contains("多计费标准")
							&& !monthusers.isEmpty()) {
						List<Feecriteriontopark> feecriteriontoparks = feecriterionToParkService
								.getByParkAndType(park.getId(), monthusers.get(0).getType());
						if (!feecriteriontoparks.isEmpty()) {
							feeCriterion = criterionService.getById(feecriteriontoparks.get(0).getCriterionid());
						}
					}

					if (charge.getParkDesc().contains("包月车")) {
						String expirationTime = Utility.formatDatetime(monthusers.get(0).getEndtime());

						monthusers = monthUserDao.getByCarnumberAndPark(cardNumber, park.getId());

						if (charge != null && (!StringUtils.isEmpty(expirationTime))) {
							Date tempTime = null;
							try {
								tempTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(expirationTime);
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							logger.info("入场时间：" + charge.getEntranceDate());
							if ((charge.getEntranceDate().compareTo(tempTime) < 0)
									&& (tempTime.compareTo(new Date()) < 0)) {

								charge.setValidTimeStart(expirationTime);

							}
						}
					}

					// 时间优惠券
					if (Integer.valueOf(charge.getDiscountType()) == 4) {
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
						Calendar nowTime = Calendar.getInstance();
						if (StringUtils.isBlank(charge.getValidTimeStart())) {
							nowTime.setTime(charge.getEntranceDate());
						} else {
							nowTime.setTime(new SimpleDateFormat().parse(charge.getValidTimeStart()));
						}
						nowTime.add(Calendar.MINUTE, charge.getDiscount().intValue());
						charge.setValidTimeStart(sdf.format(nowTime.getTime()));
						logger.info(charge.getCardNumber() + "修改计费时间为" + charge.getValidTimeStart());
					}

					calExpensewithData(charge, exitDate, true, monthusers, park, feeCriterion);
				}
			}
		}
		return charges;
	}

	@Override
	public List<PosChargeData> queryDebtWithParkId(String cardNumber, Date exitDate, Integer parkId) throws Exception {
		// TODO Auto-generated method stub
		List<PosChargeData> charges = chargeDao.getDebtWithParkId(cardNumber, parkId);
		for (PosChargeData charge : charges) {
			if (charge.getExitDate() == null) {
				Park park = parkService.getParkById(charge.getParkId());
				if (park.getType() == 1) {
					this.calExpenseType1(charge, exitDate, true);
				} else {
					// this.calExpense(charge, exitDate, true);
					List<Monthuser> monthusers = monthUserService.getByCarnumberAndPark(cardNumber, parkId);
					FeeCriterion feeCriterion = criterionService.getById(park.getFeeCriterionId());
					if (park.getDescription() != null && park.getDescription().contains("多计费标准")
							&& !monthusers.isEmpty()) {
						List<Feecriteriontopark> feecriteriontoparks = feecriterionToParkService
								.getByParkAndType(park.getId(), monthusers.get(0).getType());
						if (!feecriteriontoparks.isEmpty()) {
							feeCriterion = criterionService.getById(feecriteriontoparks.get(0).getCriterionid());
						}
					}

					if (charge.getParkDesc().contains("包月车")) {
						String expirationTime = Utility.formatDatetime(monthusers.get(0).getEndtime());
						monthusers = monthUserDao.getByCarnumberAndPark(cardNumber, park.getId());

						if (charge != null && (!StringUtils.isEmpty(expirationTime))) {
							Date tempTime = null;
							try {
								tempTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(expirationTime);
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							logger.info("入场时间：" + charge.getEntranceDate());
							if ((charge.getEntranceDate().compareTo(tempTime) < 0)
									&& (tempTime.compareTo(new Date()) < 0)) {

								charge.setValidTimeStart(expirationTime);

							}
						}
					}
					// 时间优惠券
					if (Integer.valueOf(charge.getDiscountType()) == 4) {
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
						Calendar nowTime = Calendar.getInstance();
						if (StringUtils.isBlank(charge.getValidTimeStart())) {
							nowTime.setTime(charge.getEntranceDate());
						} else {
							nowTime.setTime(new SimpleDateFormat().parse(charge.getValidTimeStart()));
						}
						nowTime.add(Calendar.MINUTE, charge.getDiscount().intValue());
						charge.setValidTimeStart(sdf.format(nowTime.getTime()));
						logger.info(charge.getCardNumber() + "修改计费时间为" + charge.getValidTimeStart());
					}

					calExpensewithData(charge, exitDate, true, monthusers, park, feeCriterion);
				}
			}
		}
		return charges;
	}

	@Override
	public List<PosChargeData> selectPosdataByParkAndRange(Date startDay, Date endDay, int parkId) {
		// TODO Auto-generated method stub
		return chargeDao.selectPosdataByParkAndRange(startDay, endDay, parkId);
	}

	@Override
	public Map<String, Object> getParkChargeByDay(int parkId, String day) {
		// TODO Auto-generated method stub
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date parsedStartDay = null;
		try {
			parsedStartDay = sdf.parse(day + " 00:00:00");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Date parsedEndDay = null;
		try {
			parsedEndDay = sdf.parse(day + " 23:59:59");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		List<PosChargeData> posChargeDatas = selectPosdataByParkAndRange(parsedStartDay, parsedEndDay, parkId);
		Map<String, Object> retmap = new HashMap<>();
		float chargeTotal = 0;
		float realReceiveMoney = 0;
		for (PosChargeData posData : posChargeDatas) {
			chargeTotal += posData.getChargeMoney();
			realReceiveMoney += posData.getGivenMoney() + posData.getPaidMoney() - posData.getChangeMoney();
		}
		retmap.put("totalMoney", chargeTotal);
		retmap.put("realMoney", realReceiveMoney);
		return retmap;
	}

	@Override
	public List<PosChargeData> queryCurrentDebt(String cardNumber, Date exitDate) throws Exception {
		List<PosChargeData> charges = chargeDao.getDebt(cardNumber);
		List<PosChargeData> tmPosChargeDatas = new ArrayList<>();
		for (PosChargeData charge : charges) {
			if (charge.getExitDate() == null) {
				tmPosChargeDatas.add(charge);
			}
		}
		for (PosChargeData tmpcharge : tmPosChargeDatas) {
			this.calExpense(tmpcharge, exitDate, true);
		}
		return tmPosChargeDatas;
	}

	@Override
	public List<PosChargeData> getByCardNumber(String cardNumber) {
		// TODO Auto-generated method stub
		return chargeDao.getByCardNumber(cardNumber);
	}

	@Override
	public List<PosChargeData> getByParkName(String parkName) {
		// TODO Auto-generated method stub
		return chargeDao.getByParkName(parkName);
	}

	@Override
	public List<PosChargeData> repay(String cardNumber, double money) throws Exception {
		double theMoney = money;
		List<PosChargeData> charges = this.getCharges(cardNumber);
		for (PosChargeData charge : charges) {
			if (money >= charge.getUnPaidMoney()) {
				money -= charge.getUnPaidMoney();
				charge.setPaidCompleted(true);
				charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
				this.update(charge);
			}
		}

		if (money >= 0) {
			int count = charges.size();
			PosChargeData lastCharge = charges.get(0);
			lastCharge.setChangeMoney(lastCharge.getChangeMoney() + money);
			lastCharge.setGivenMoney(theMoney + lastCharge.getGivenMoney());
			// Outsideparkinfo
			// outsideparkinfo=outsideParkInfoService.getByParkidAndDate(lastCharge.getParkId());
			// outsideparkinfo.setRealmoney((float)
			// (outsideparkinfo.getRealmoney()+lastCharge.getPaidMoney()+lastCharge.getGivenMoney()-lastCharge.getChangeMoney()));
			// outsideparkinfo.setPossigndate(new Date());
			// outsideParkInfoService.updateByPrimaryKeySelective(outsideparkinfo);
			this.update(lastCharge);
		}
		return charges;
	}

	@Override
	public List<Map<String, Object>> getFeeOperatorChargeData(Date startDate, Date endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getFeeOperatorChargeData(startDate, endDate);
	}

	@Override
	public List<PosChargeData> getByRange(int parkId, Date startDate, Date endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getByRange(parkId, startDate, endDate);
	}

	@Override
	public List<PosChargeData> getByParkAndDay(int parkId, String date) throws ParseException {
		// TODO Auto-generated method stub
		SimpleDateFormat sFormat = new SimpleDateFormat(Constants.DATEFORMAT);
		Date startDate = sFormat.parse(date + " 00:00:00");
		Date endDate = sFormat.parse(date + " 23:59:59");
		return chargeDao.getByRange(parkId, startDate, endDate);
	}

	@Override
	public List<PosChargeData> getAllByDay(String date) throws ParseException {
		// TODO Auto-generated method stub
		SimpleDateFormat sFormat = new SimpleDateFormat(Constants.DATEFORMAT);
		Date startDate = sFormat.parse(date + " 00:00:00");
		Date endDate = sFormat.parse(date + " 23:59:59");
		return chargeDao.getAllByDay(startDate, endDate);
	}

	@Override
	public List<PosChargeData> getByParkAndDayRange(int parkId, String startDate, String endDate)
			throws ParseException {
		// TODO Auto-generated method stub
		SimpleDateFormat sFormat = new SimpleDateFormat(Constants.DATEFORMAT);
		Date dstartDate = sFormat.parse(startDate + " 00:00:00");
		Date dendDate = sFormat.parse(endDate + " 23:59:59");
		return chargeDao.getByRange(parkId, dstartDate, dendDate);
	}

	@Override
	public List<PosChargeData> getAllByDayRange(String startDate, String endDate) throws ParseException {
		// TODO Auto-generated method stub
		SimpleDateFormat sFormat = new SimpleDateFormat(Constants.DATEFORMAT);
		Date dstartDate = sFormat.parse(startDate + " 00:00:00");
		Date dendDate = sFormat.parse(endDate + " 23:59:59");
		return chargeDao.getAllByDay(dstartDate, dendDate);
	}

	@Override
	public List<PosChargeData> getPageArrearage(int low, int count) {
		// TODO Auto-generated method stub
		return chargeDao.getPageArrearage(low, count);
	}

	@Override
	public List<PosChargeData> getPageArrearageByParkId(int parkId, int start, int count) {
		// TODO Auto-generated method stub
		return chargeDao.getPageArrearageByParkId(parkId, start, count);
	}

	@Override
	public List<PosChargeData> getPageByParkId(int parkId, int start, int count) {
		// TODO Auto-generated method stub
		return chargeDao.getPageByParkId(parkId, start, count);
	}

	@Override
	public List<PosChargeData> getByParkIdAndCardNumber(Integer parkId, String cardNumber) {
		// TODO Auto-generated method stub
		return chargeDao.getByParkIdAndCardNumber(parkId, cardNumber);
	}

	@Override
	public List<PosChargeData> getParkCarportStatusToday(int parkId, Date tmpdate) {
		// TODO Auto-generated method stub
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

		String day = sdf.format(tmpdate) + " 00:00:00";
		return chargeDao.getParkCarportStatusToday(parkId, day);
	}

	@Override
	public Outsideparkinfo getOutsideparkinfoByOrigin(int parkId, String day) {
		// TODO Auto-generated method stub
		Park park = parkService.getParkById(parkId);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date parsedStartDay = null;
		try {
			parsedStartDay = sdf.parse(day + " 00:00:00");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Date parsedEndDay = null;
		try {
			parsedEndDay = sdf.parse(day + " 23:59:59");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Outsideparkinfo outsideparkinfo = new Outsideparkinfo();
		// Outsideparkinfo outsideparkinfo2 = new Outsideparkinfo();
		// outsideparkinfo2 = outsideParkInfoService.getByParkidAndDate(parkId, new
		// Date());
		//
		// if (outsideparkinfo2 != null && outsideparkinfo2.getPossigndate() != null) {
		// outsideparkinfo.setPossigndate(outsideparkinfo2.getPossigndate());
		// }
		// List<PosChargeData> posChargeDatas =
		// selectPosdataByParkAndRange(parsedStartDay, parsedEndDay, parkId);
		Map<String, Object> parkSumData = selectPosdataSumByParkAndRange(parsedStartDay, parsedEndDay, parkId);
		// System.out.println(parkSumData.toString());
		Map<String, Object> parkInCount = calInByParkAndRange(parkId, parsedStartDay, parsedEndDay);
		// System.out.println(parkInCount.toString());
		Map<String, Object> parkOutCount = calOutByParkAndRange(parkId, parsedStartDay, parsedEndDay);
		// System.out.println(parkOutCount.toString());
		outsideparkinfo.setParkid(parkId);
		outsideparkinfo.setCarportcount(park.getPortCount());
		outsideparkinfo.setUnusedcarportcount(park.getPortLeftCount());

		outsideparkinfo.setAmountmoney(parkSumData == null ? 0 : (float) (double) parkSumData.get("chargeMoney"));
		outsideparkinfo.setRealmoney((parkSumData == null ? 0 : (float) (double) parkSumData.get("givenMoney"))
				+ (parkSumData == null ? 0 : (float) (double) parkSumData.get("paidMoney"))
				- (parkSumData == null ? 0 : (float) (double) parkSumData.get("changeMoney")));
		outsideparkinfo.setEntrancecount(parkInCount == null ? 0 : (int) (long) parkInCount.get("count"));
		outsideparkinfo.setOutcount(parkOutCount == null ? 0 : (int) (long) parkOutCount.get("count"));
		outsideparkinfo.setArrearage(outsideparkinfo.getAmountmoney() - outsideparkinfo.getRealmoney());

		return outsideparkinfo;
	}

	@Override
	public Outsideparkinfo getOutsideparkinfoByOriginMoney(int id, String day) {

		return null;
	}

	@Override
	public List<PosChargeData> getArrearageByCardNumber(String cardNumber) {
		// TODO Auto-generated method stub
		return chargeDao.getArrearageByCardNumber(cardNumber);
	}

	@Override
	public List<PosChargeData> getByParkAuthority(String userName) {
		// TODO Auto-generated method stub
		List<Park> parkList = parkService.getParks();
		if (userName != null)
			parkList = parkService.filterPark(parkList, userName);
		int num = 120 / parkList.size();
		if (num < 1) {
			num = 2;
		}
		List<PosChargeData> posChargeDatas = new ArrayList<PosChargeData>();
		for (Park park : parkList) {
			List<PosChargeData> tmPosChargeDatas = getPageByParkId(park.getId(), 0, num);
			posChargeDatas.addAll(tmPosChargeDatas);
		}
		return posChargeDatas;
	}

	@Override
	public Integer deleteByParkIdAndDate(int parkId, String startDate, String endDate) {
		// TODO Auto-generated method stub
		return chargeDao.deleteByParkIdAndDate(startDate, endDate, parkId);
	}

	@Override
	public int deleteById(int id) {
		// TODO Auto-generated method stub
		return chargeDao.deleteById(id);
	}

	@Override
	public List<PosChargeData> selectPosdataByParkAndRangeAndCarportNumber(Date startDay, Date endDay, int parkId,
			int carportNumber) {
		// TODO Auto-generated method stub
		return chargeDao.selectPosdataByParkAndRangeAndCarportNumber(startDay, endDay, parkId, carportNumber);
	}

	@Override
	public List<PosChargeData> hardwareRecord(Integer parkId, String startDate, String endDate) throws Exception {
		// TODO Auto-generated method stub
		List<Map<String, Object>> carportStatusDetails = carportStatusDetailDAO.getDetailByParkIdAndDateRange(parkId,
				startDate, endDate);
		List<PosChargeData> posChargeDatas = new ArrayList<>();
		SimpleDateFormat sFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		for (Map<String, Object> c : carportStatusDetails) {
			if (c.get("endTime") != null) {
				PosChargeData tmPosChargeData = new PosChargeData();
				// tmPosChargeData.setCardNumber(Integer.toString(c.getCarportId()));
				tmPosChargeData.setEntranceDate(sFormat.format(c.get("startTime")));
				tmPosChargeData.setExitDate(sFormat.format(c.get("endTime")));
				tmPosChargeData.setParkId(parkId);
				tmPosChargeData.setPortNumber(String.valueOf(c.get("carportNumber")));
				tmPosChargeData.setIsLargeCar(false);
				tmPosChargeData.setIsOneTimeExpense(0);
				posChargeDatas.add(tmPosChargeData);
			}
		}
		for (PosChargeData p : posChargeDatas) {
			this.calExpense(p, p.getExitDate(), true);
		}
		return posChargeDatas;
	}

	@Override
	public PosChargeData updateRejectReason(String cardNumber, String rejectReason) throws Exception {
		// TODO Auto-generated method stub
		List<PosChargeData> charges = this.getCharges(cardNumber);
		if (charges.isEmpty()) {
			return null;
		}
		PosChargeData lastCharge = charges.get(0);
		lastCharge.setRejectReason(rejectReason);
		this.update(lastCharge);
		return lastCharge;
	}

	@Override
	public List<PosChargeData> getByCardNumberAndPort(String cardNumber, Integer portNumber) {
		// TODO Auto-generated method stub
		return chargeDao.getByCardNumberAndPort(cardNumber, portNumber);
	}

	@Override
	public void calExpenseType1(PosChargeData charge, Date exitDate, Boolean isQuery) throws ParseException {
		// TODO Auto-generated method stub
		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(charge.getEntranceDate());
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		Park park = parkService.getParkById(charge.getParkId());
		Integer criterionId = park.getFeeCriterionId();
		FeeCriterion criterion = criterionService.getById(criterionId);
		String nightStartHour = "24";
		String nightEndHour = "0";
		Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
		double money = 0;
		for (String name : dates.keySet()) {
			Date startDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(name);
			Date endDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name));
			long diffs = endDate.getTime() - startDate.getTime() - criterion.getFreemins() * 60 * 1000;
			if (diffs > 1000 * 60 * 60 * 12) {
				money += 10;
			}
			if (diffs <= 1000 * 60 * 60 * 12 && diffs > 0) {
				money += 10;
			}
		}
		charge.setExitDate(endTime);
		if (!isQuery) {
			this.update(charge);
		}
	}

	@Override
	public PosChargeData newFeeCalcExpense(PosChargeData charge, Date exitDate, Boolean isQuery) throws Exception {
		// TODO Auto-generated method stub
		if (exitDate == null) {
			exitDate = new Date();
		}
		charge.setExitDate1(exitDate);
		Park park = parkService.getParkById(charge.getParkId());
		Integer criterionId = park.getFeeCriterionId();
		FeeCriterion criterion = criterionService.getById(criterionId);
		// 入场免费时间处理
		int freeMinutes = criterion.getFreemins();

		Date entranceDate = new Date(charge.getEntranceDate().getTime() + freeMinutes * 60 * 1000);

		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(entranceDate);
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "8";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		if (entranceDate.getTime() > exitDate.getTime()) {
			charge.setChargeMoney(0);
			return charge;
		}
		Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
		double money = 0;
		// for(String name:dates.keySet()){
		// Date startDate=new
		// SimpleDateFormat(Constants.DATEFORMAT).parse(name);
		// Date endDate=new
		// SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name));
		// String nightStartHour2 = "20";
		// String nightEndHour2 = "8";
		// Map<String,String> dates2=formatTime.format(new
		// SimpleDateFormat(Constants.DATEFORMAT).format(startDate), new
		// SimpleDateFormat(Constants.DATEFORMAT).format(endDate),
		// nightStartHour2,nightEndHour2);
		// for(String name2:dates2.keySet()){
		// Date startDate2=new
		// SimpleDateFormat(Constants.DATEFORMAT).parse(name2);
		// Date endDate2=new
		// SimpleDateFormat(Constants.DATEFORMAT).parse(dates2.get(name2));
		//
		// }
		// long
		// diffs=endDate.getTime()-startDate.getTime()-criterion.getFreemins()*60*1000;
		// if (diffs>1000*60*60*12) {
		// money+=10;
		// }
		// if (diffs<=1000*60*60*12&&diffs>0) {
		// money+=10;
		// }
		// }

		double step1Price = criterion.getStep1price();
		double step2Price = criterion.getStep2price();
		int step1Minutes = 15;
		int step2minutes = 60;
		if (charge.getIsLargeCar()) {
			step1Price = criterion.getStep1pricelarge();
			step2Price = criterion.getStep2pricelarge();
		}
		for (String name : dates.keySet()) {
			logger.info("计费**车牌号:" + charge.getCardNumber() + "时间:" + name + "-" + dates.get(name));
			Date startDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(name);
			Date endDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name));
			String startd = name.substring(11, 13);
			if (Integer.parseInt(startd) >= Integer.parseInt(nightEndHour)
					&& Integer.parseInt(startd) < Integer.parseInt(nightStartHour)) {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (float) (1000 * 60 * step1Minutes));
				money += hours * step1Price;
			} else {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (float) (1000 * 60 * step2minutes));
				money += hours * step2Price;
			}
			logger.info("计费**车牌号:" + charge.getCardNumber() + "费用:" + money);
		}
		charge.setChargeMoney(money);
		return charge;
	}

	// 24小时
	@Override
	public PosChargeData newFeeCalcExpense4(PosChargeData charge, FeeCriterion criterion, Date exitDate,
			Boolean isQuery, Park park) throws Exception {
		Date enterDate = charge.getEntranceDate();
		Date enterDateNew = new Date(enterDate.getTime() + criterion.getFreemins() * 1000 * 60);
		if (!StringUtils.isBlank(criterion.getExplaination()) && criterion.getExplaination().contains("收费剔除免费时段")) {
			long diff3 = (long) Math.ceil((exitDate.getTime() - enterDateNew.getTime()) / (1000 * 60f));
			if (diff3 > 0) {
				enterDateNew = enterDate;
			}

		}

		long diff = (long) Math.ceil((exitDate.getTime() - enterDateNew.getTime()) / (1000 * 60f));
		int rate = 1;
		if (charge.getIsLargeCar()) {
			// 大车 有关键字 费率加倍
			if (StringUtils.isNotBlank(criterion.getOther())) {
				String ctrOther = criterion.getOther();
				if (ctrOther.contains("MaxRateToSmallCar")) {
					rate = 2;
				}
			}
		}
		if (diff <= 0) {
			charge.setChargeMoney(0);
			charge.setEntranceDate1(enterDate);
			charge.setExitDate1(new Date());
			return charge;
		}
		int leftMinuts = (int) Math.ceil((diff % (60 * 24f)));
		int days = (int) (diff / (60 * 24f));
		logger.info(charge.getCardNumber() + "[24计费标准计算]" + "停车时长为" + days + "天" + leftMinuts + "分钟");
		double money = Math.min(days * OneDayMaxFee(charge, criterion, park), days * criterion.getMaxexpense() * rate);

		Date newEnterTime = new Date(exitDate.getTime() - leftMinuts * 1000 * 60);
		charge.setEntranceDate1(newEnterTime);

		if (charge.getIsLargeCar()) {
			calFeeLargeCarWithData(charge, exitDate, isQuery, park, criterion);
		} else {
			calFeeSmallCarWithData(charge, exitDate, isQuery, park, criterion);
		}
		charge.setEntranceDate1(enterDate);
		charge.setChargeMoney(charge.getChargeMoney() + money);
		return charge;
	}

	public PosChargeData hexiananliangxuefu(PosChargeData charge, FeeCriterion criterion, Date exitDate,
			Boolean isQuery, Park park) throws ParseException {
		Date enterDate = charge.getEntranceDate();
		Date enterDateNew = new Date(enterDate.getTime() + criterion.getFreemins() * 1000 * 60);
		long diff = (long) Math.ceil((exitDate.getTime() - enterDateNew.getTime()) / (1000 * 60f));
		if (diff <= 0) {
			charge.setChargeMoney(0);
			charge.setEntranceDate1(enterDate);
			charge.setExitDate1(new Date());
			return charge;
		}
		int leftMinuts = (int) Math.ceil((diff % (60 * 24f)));
		int days = (int) (diff / (60 * 24f));
		// logger.info(String.format("车牌号:%s - 停车时长：%d 天 %d 分钟",
		// charge.getCardNumber(),days,leftMinuts));
		double money = 0;
		if (leftMinuts <= 180 && leftMinuts > 60) {
			money = 2;
		} else if (leftMinuts > 180 && leftMinuts <= 360) {
			money = 6;
		} else if (leftMinuts > 360 && leftMinuts <= 480) {
			money = 7;
		} else if (leftMinuts > 480) {
			money = 8;
		}
		logger.info(String.format("车牌号:%s - 停车时长：%d 天 %d 分钟, 停车费：%.1f", charge.getCardNumber(), days, leftMinuts,
				money + days * 8));
		charge.setExitDate1(exitDate);
		charge.setChargeMoney(money + days * 8);
		return charge;
	}

	// 计算一天最大计费
	public double OneDayMaxFee(PosChargeData posChargeData, FeeCriterion feeCriterion, Park park)
			throws ParseException {
		PosChargeData tmpp = new PosChargeData();
		tmpp.setEntranceDate("2019-01-01 00:00:01");
		tmpp.setExitDate("2019-01-01 23:59:59");
		if (posChargeData.getIsLargeCar()) {
			calFeeLargeCarWithData(tmpp, new SimpleDateFormat(Constants.DATEFORMAT).parse("2019-01-01 23:59:59"), true,
					park, feeCriterion);
		} else {
			calFeeSmallCarWithData(tmpp, new SimpleDateFormat(Constants.DATEFORMAT).parse("2019-01-01 23:59:59"), true,
					park, feeCriterion);
		}
		return tmpp.getChargeMoney();
	}

	public PosChargeData taizhougonghang(PosChargeData charge, FeeCriterion criterion, Date exitDate, Boolean isQuery,
			Park park, List<Monthuser> monthusers) throws ParseException {
		Date tmpentranceDate = charge.getEntranceDate();
		Date dateTime1 = getEntranceDate(charge, criterion);
		if (dateTime1.getTime() >= exitDate.getTime()) {
			logger.info(charge.getCardNumber() + "在免费时段内" + Utility.formatDatetime(dateTime1) + "-"
					+ Utility.formatDatetime(exitDate));
			charge.setChargeMoney(0);
			charge.setUnPaidMoney(0);
			charge.setPaidCompleted(true);
			charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
			charge.setExitDate1(new Date());
			charge.setOther2("免费时段");
			if (!isQuery) {
				this.update(charge);
			}
			return charge;
		}
		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(dateTime1);
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "07";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
		for (String name : dates.keySet()) {
			charge.setEntranceDate(name);
			if (isNight(charge, criterion, name)) {

				double diff = Math.ceil((new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)).getTime()
						- charge.getEntranceDate().getTime()) / (1000 * 60 * 60f));
				if (diff >= 5) {
					charge.setChargeMoney(25 + charge.getChargeMoney());
				} else {
					charge.setChargeMoney(5 * diff + charge.getChargeMoney());
				}
			} else {
				this.calExpenseTaizhouGonghang(charge,
						new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)), isQuery, park, criterion);
			}
		}
		charge.setEntranceDate1(tmpentranceDate);
		charge.setExitDate(endTime);
		if (charge.getPaidMoney() >= charge.getChargeMoney() && !isQuery) {
			charge.setUnPaidMoney(0);
			charge.setPaidCompleted(true);
			charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
			charge.setChangeMoney(charge.getPaidMoney() - charge.getChargeMoney());
		} else {
			charge.setUnPaidMoney(charge.getChargeMoney() - charge.getPaidMoney());
		}
		if (!isQuery) {
			this.update(charge);
		}

		return charge;
	}

	//
	public PosChargeData chongqingyongchuanjifei(PosChargeData charge, FeeCriterion criterion, Date exitDate,
			Boolean isQuery, Park park, List<Monthuser> monthusers) throws ParseException {
		logger.info(charge.getCardNumber() + "永川计费");
		Date enterDate = charge.getEntranceDate();
		Date enterDateNew = new Date(enterDate.getTime() + criterion.getFreemins() * 1000 * 60);
		long diff = (long) Math.ceil((exitDate.getTime() - enterDateNew.getTime()) / (1000 * 60f));
		if (!monthusers.isEmpty() && monthusers.get(0).getType() == 2) {
			charge.setPayType(20);
		}
		if (diff <= 0) {
			charge.setChargeMoney(0);
			charge.setEntranceDate1(enterDate);
			charge.setExitDate1(new Date());
			logger.info(charge.getCardNumber() + "diff费用为0");
			return charge;
		}
		int leftMinuts = (int) Math.ceil((diff % (60 * 24)));
		int days = (int) (diff / (60 * 24));
		logger.info(charge.getCardNumber() + "天数" + days + "分钟数" + leftMinuts);
		double money = days * criterion.getMaxexpense();
		Date newEnterTime = new Date(exitDate.getTime() - leftMinuts * 1000 * 60 - criterion.getFreemins() * 1000 * 60);
		charge.setEntranceDate1(newEnterTime);
		if (charge.getIsLargeCar()) {
			// 此计算大车费用 不要提前剔除免费时段
			calExpenseLargeCarWithData(charge, exitDate, isQuery, park, criterion);
		} else {
			// 此计算小车费用 不要提前剔除免费时段
			calExpenseSmallCarWithData(charge, exitDate, isQuery, park, criterion);
		}
		charge.setEntranceDate1(enterDate);

		if (charge.getChargeMoney() > 10 && leftMinuts <= 12 * 60) {
			charge.setChargeMoney(10);
		}
		if (leftMinuts > 12 * 60) {
			int hours = (int) Math.ceil((leftMinuts - 720) / 60f);
			charge.setChargeMoney((10 + hours * 2) > 20 ? 20 : (10 + hours * 2));
			logger.info(charge.getCardNumber() + "超过12小时" + charge.getChargeMoney());
		}
		charge.setChargeMoney(charge.getChargeMoney() + money);
		// 内部48小时内
		if (!monthusers.isEmpty() && monthusers.get(0).getType() == 2 && days <= 1) {
			charge.setChargeMoney(charge.getChargeMoney() / 2);
			logger.info(charge.getCardNumber() + "内部职工车,费用减半" + charge.getChargeMoney());
		}
		if (!monthusers.isEmpty() && monthusers.get(0).getType() == 2 && days > 1) {
			charge.setChargeMoney(charge.getChargeMoney() - 20);
			logger.info(charge.getCardNumber() + "超过两天,费用减去20" + charge.getChargeMoney());
		}
		if (!monthusers.isEmpty() && monthusers.get(0).getType() == 2) {
			if (monthusers.get(0).getPayment() >= charge.getChargeMoney()) {
				charge.setPaidCompleted(true);
				charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
				charge.setPaidMoney(charge.getChargeMoney());
				charge.setPayType(20);// 存值卡
				Monthuserconsumerrecord monthuserconsumerrecord = new Monthuserconsumerrecord();
				monthuserconsumerrecord.setBeforerecharge((double) monthusers.get(0).getPayment());
				monthuserconsumerrecord.setParkid(charge.getParkId());
				monthuserconsumerrecord.setParkdesc(charge.getParkDesc());
				monthuserconsumerrecord.setOperationtype(0);
				monthuserconsumerrecord.setPoschargedataid(charge.getId());
				monthuserconsumerrecord.setPlatenumber(charge.getCardNumber());
				monthuserconsumerrecord.setName(monthusers.get(0).getOwner());
				monthuserconsumerrecord.setShouldcharge(charge.getChargeMoney());

				monthusers.get(0).setPayment((float) (monthusers.get(0).getPayment() - charge.getChargeMoney()));
				monthuserconsumerrecord.setBalance((double) monthusers.get(0).getPayment());
				if (!isQuery) {
					monthUserService.updateByPrimaryKeySelective(monthusers.get(0));
					monthuserConsumerService.insertSelective(monthuserconsumerrecord);
					logger.info(charge.getCardNumber() + "-储值卡扣费" + charge.getChargeMoney() + "-余额"
							+ monthusers.get(0).getPayment());
				}
			} else {
				charge.setPayType(30);// 储值卡过期转现金
				// logger.info(charge.getCardNumber()+"储值卡余额不足");
			}
		}
		// if (charge.getChargeMoney()<0.1) {
		// charge.setPayType(20);
		// }
		return charge;

	}

	// 按次
	@Override
	public PosChargeData newFeeCalcExpense1(PosChargeData charge, FeeCriterion criterion, Date exitDate,
			Boolean isQuery) throws Exception {
		if (exitDate == null) {
			exitDate = new Date();
		}
		charge.setExitDate1(exitDate);
		Date entranceDate = new Date(charge.getEntranceDate().getTime() + criterion.getFreemins() * 60 * 1000);
		if (entranceDate.getTime() >= exitDate.getTime()) {
			charge.setChargeMoney(0);
			return charge;
		}
		entranceDate = new Date(charge.getEntranceDate().getTime());
		float price = criterion.getStep1price();
		if (charge.getIsLargeCar()) {
			price = criterion.getStep1pricelarge();
		}
		if (criterion.getIsonetimeexpense() == 0) {
			double diff = exitDate.getTime() - entranceDate.getTime();
			double size = Math.ceil((diff / (1000 * 60)) / (float) criterion.getTimeoutpriceinterval());
			charge.setChargeMoney(price * size);
		} else {
			String nightStartHour = "24";
			String nightEndHour = "0";
			String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(entranceDate);
			String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
			Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
			charge.setChargeMoney(price * dates.size());
		}
		return charge;
	}

	// 夹岗
	public PosChargeData calJiagang(PosChargeData charge, FeeCriterion criterion, Date exitDate, Boolean isQuery)
			throws ParseException {
		if (exitDate == null) {
			exitDate = new Date();
		}
		charge.setExitDate1(exitDate);

		// 入场免费时间处理
		int freeMinutes = criterion.getFreemins();

		Date entranceDate = new Date(charge.getEntranceDate().getTime() + freeMinutes * 60 * 1000);

		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(entranceDate);
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "8";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		if (entranceDate.getTime() > exitDate.getTime()) {
			charge.setChargeMoney(0);
			return charge;
		}
		Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
		double money = 0;

		double step1Price = criterion.getStep1price();
		double step2Price = criterion.getStep3price();
		int step1Minutes = 15;
		int step2minutes = 60;
		step1Minutes = criterion.getTimeoutpriceinterval();
		step2minutes = criterion.getTimeoutpriceinterval2();
		if (charge.getIsLargeCar()) {
			step1Price = criterion.getStep1pricelarge();
			step2Price = criterion.getStep3pricelarge();
		}
		for (String name : dates.keySet()) {
			logger.info("夹岗计费**车牌号:" + charge.getCardNumber() + "时间:" + name + "-" + dates.get(name));
			Date startDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(name);
			Date endDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name));
			String startd = name.substring(11, 13);
			if (Integer.parseInt(startd) >= Integer.parseInt(nightEndHour)
					&& Integer.parseInt(startd) < Integer.parseInt(nightStartHour)) {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step1Minutes));
				if (hours * step1Price > criterion.getMaxexpense()) {
					money += criterion.getMaxexpense();
				} else {
					money += hours * step1Price;
				}

				logger.info("夹岗计费**车牌号:" + charge.getCardNumber() + "费用:" + hours * step1Price);
			} else {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step2minutes));
				if (hours * step2Price > criterion.getMaxexpense() / 2) {
					money += (criterion.getMaxexpense() / 2);
				} else {
					money += hours * step2Price;
				}
				logger.info("夹岗计费**车牌号:" + charge.getCardNumber() + "费用:" + hours * step2Price);
			}
			logger.info("夹岗计费**车牌号:" + charge.getCardNumber() + "累积费用:" + money);
		}
		charge.setChargeMoney(money);
		return charge;
	}

	// 南京南站
	public PosChargeData nanjingNan(PosChargeData charge, FeeCriterion criterion, Date exitDate, Boolean isQuery)
			throws ParseException {
		if (exitDate == null) {
			exitDate = new Date();
		}
		charge.setExitDate1(exitDate);

		// 入场免费时间处理
		int freeMinutes = 15;
//		if (jedisClient.get("carFreeValidate" + charge.getParkId() + charge.getCardNumber()) != null) {
//			logger.info(charge.getCardNumber() + "离场一小时内入场");
//			freeMinutes = 0;
//		} else {
//			jedisClient.set("carFreeValidate" + charge.getParkId() + charge.getCardNumber(), "ok", 3600);
//		}
		Date entranceDate = new Date(charge.getEntranceDate().getTime() + freeMinutes * 60 * 1000);

		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(entranceDate);
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "08";

		if (entranceDate.getTime() > exitDate.getTime()) {
			charge.setChargeMoney(0);
			return charge;
		}
		Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
		double money = 0;

		double step1Price = 2;
		double step2Price = 1;
		int step1Minutes = 15;
		int step2minutes = 60;
		double lightmax = 48;
		double nightmax = 6;
		if (charge.getIsLargeCar()) {
			step1Price = 3;
			step2Price = 1.5;
			lightmax = 72;
			nightmax = 9;
		}

		for (String name : dates.keySet()) {
			logger.info("南京南计费**车牌号:" + charge.getCardNumber() + "时间:" + name + "-" + dates.get(name));
			Date startDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(name);
			Date endDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name));
			String startd = name.substring(11, 13);
			if (Integer.parseInt(startd) >= Integer.parseInt(nightEndHour)
					&& Integer.parseInt(startd) < Integer.parseInt(nightStartHour)) {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step1Minutes));
				if (hours * step1Price > lightmax) {
					money += lightmax;
				} else {
					money += hours * step1Price;
				}

				logger.info("南京南计费**车牌号:" + charge.getCardNumber() + "费用:" + hours * step1Price);
			} else {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step2minutes));
				if (hours * step2Price > nightmax) {
					money += nightmax;
				} else {
					money += hours * step2Price;
				}
				logger.info("南京南计费**车牌号:" + charge.getCardNumber() + "费用:" + hours * step2Price);
			}
			logger.info("南京南计费**车牌号:" + charge.getCardNumber() + "累积费用:" + money);
		}
		charge.setChargeMoney(money);
		return charge;

	}

	// 白天晚上模板
	@Override
	public PosChargeData newFeeCalcExpense2(PosChargeData charge, FeeCriterion criterion, Date exitDate,
			Boolean isQuery) throws Exception {
		if (exitDate == null) {
			exitDate = new Date();
		}
		charge.setExitDate1(exitDate);

		// 入场免费时间处理
		int freeMinutes = criterion.getFreemins();

		Date entranceDate = new Date(charge.getEntranceDate().getTime() + freeMinutes * 60 * 1000);
		String startTime = null;
		if (StringUtils.isNotBlank(charge.getValidTimeStart())) {
			startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(
					new Date(new SimpleDateFormat(Constants.DATEFORMAT).parse(charge.getValidTimeStart()).getTime()
							+ freeMinutes * 60 * 1000));
		} else {
			startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(entranceDate);
		}
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "8";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		if (entranceDate.getTime() > exitDate.getTime()) {
			charge.setChargeMoney(0);
			return charge;
		}
		double money = 0;

		double step1Price = criterion.getStep1price();
		double step2Price = criterion.getStep3price();
		int step1Minutes = 15;
		int step2minutes = 60;
		step1Minutes = criterion.getTimeoutpriceinterval();
		step2minutes = criterion.getTimeoutpriceinterval2();
		if (charge.getIsLargeCar()) {
			step1Price = criterion.getStep1pricelarge();
			step2Price = criterion.getStep3pricelarge();
		}
		double tempMoney = 0.0;

		Map<String, String> datesDay = formatTime.format(startTime, endTime, "24", "0");
		for (String daykey : datesDay.keySet()) {
			Map<String, String> dates0 = formatTime.format(daykey, datesDay.get(daykey), nightStartHour, nightEndHour);
			double moneytmp = 0;
			for (String name : dates0.keySet()) {
				logger.info("计费-车牌号:" + charge.getCardNumber() + "时间:" + name + "-" + dates0.get(name));
				Date startDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(name);
				Date endDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(dates0.get(name));
				String startd = name.substring(11, 13);
				if (Integer.parseInt(startd) >= Integer.parseInt(nightEndHour)
						&& Integer.parseInt(startd) < Integer.parseInt(nightStartHour)) {
					long diffs = endDate.getTime() - startDate.getTime();
					double hours = Math.ceil((double) diffs / (1000 * 60 * step1Minutes));
					if (hours * step1Price > criterion.getMaxexpense()) {
						moneytmp += criterion.getMaxexpense();
					} else {
						moneytmp += hours * step1Price;
					}
					logger.info("计费-车牌号:" + charge.getCardNumber() + "费用:" + hours * step1Price);
				} else {
					long diffs = endDate.getTime() - startDate.getTime();
					double hours = Math.ceil((double) diffs / (1000 * 60 * step2minutes));
					if (hours * step2Price > criterion.getMaxexpense()) {
						moneytmp += criterion.getMaxexpense();
					} else {
						moneytmp += hours * step2Price;
					}
					logger.info("计费-车牌号:" + charge.getCardNumber() + "费用:" + hours * step2Price);
				}
				logger.info("计费**车牌号:" + charge.getCardNumber() + "累积费用:" + moneytmp);
			}
			if (moneytmp > criterion.getMaxexpense()) {
				logger.info(charge.getCardNumber() + "达到一天最大金额" + moneytmp + "to" + criterion.getMaxexpense());
				moneytmp = criterion.getMaxexpense();
			}
			money += moneytmp;
			tempMoney = money;
			if (charge.getDiscountType() == 1) {
				money = 0;
			} else if (charge.getDiscountType() == 2) {
				money = money - charge.getDiscount() > 0 ? money - charge.getDiscount() : 0;
			} else if (charge.getDiscountType() == 3) {
				money = charge.getDiscount();
			}
		}
		charge.setPaidMoney(money);
		charge.setPaidCompleted(true);
		charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
		charge.setChargeMoney(tempMoney);
		logger.info("白天晚上 :" + charge);
		return charge;
	}

	// 众彩物流
	public PosChargeData zhongcaiwuliu(PosChargeData charge, FeeCriterion criterion, Date exitDate, Boolean isQuery)
			throws Exception {
		if (exitDate == null) {
			exitDate = new Date();
		}
		charge.setExitDate1(exitDate);
		// 入场免费时间处理
		int freeMinutes = criterion.getFreemins();
		if (charge.getIsLargeCar()) {
			freeMinutes = freeMinutes * 2;
		}
		Date entranceDate = new Date(charge.getEntranceDate().getTime() + freeMinutes * 60 * 1000);
		String startTime = "";
		if (StringUtils.isNotBlank(charge.getValidTimeStart())) {
			startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(
					new Date(new SimpleDateFormat(Constants.DATEFORMAT).parse(charge.getValidTimeStart()).getTime()
							+ freeMinutes * 60 * 1000));
		} else {
			startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(entranceDate);
		}
		logger.info(charge.getCardNumber() + " start时间" + startTime);
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "8";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		if (new SimpleDateFormat(Constants.DATEFORMAT).parse(startTime).getTime() > exitDate.getTime()) {
			charge.setChargeMoney(0);
			return charge;
		}
		double money = 0;

		double step1Price = criterion.getStep1price();
		double step2Price = criterion.getStep3price();
		int step1Minutes = 15;
		int step2minutes = 60;
		step1Minutes = criterion.getTimeoutpriceinterval();
		step2minutes = criterion.getTimeoutpriceinterval2();
		if (charge.getIsLargeCar()) {
			step1Price = criterion.getStep1pricelarge();
			step2Price = criterion.getStep3pricelarge();
		}
		double tempMoney = 0.0;

		Map<String, String> datesDay = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);

		float dayCarMax = 18;
		float nightCarMax = 6;
		if (charge.getIsLargeCar()) {
			dayCarMax = 30;
			nightCarMax = 9;
		}

		for (String name : datesDay.keySet()) {
			double moneytmp = 0;
			logger.info("计费-车牌号:" + charge.getCardNumber() + "时间:" + name + "-" + datesDay.get(name));
			Date startDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(name);
			Date endDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(datesDay.get(name));
			String startd = name.substring(11, 13);
			if (Integer.parseInt(startd) >= Integer.parseInt(nightEndHour)
					&& Integer.parseInt(startd) < Integer.parseInt(nightStartHour)) {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step1Minutes));
				if (hours * step1Price > dayCarMax) {
					moneytmp += dayCarMax;
				} else {
					moneytmp += hours * step1Price;
				}
				logger.info("计费-车牌号:" + charge.getCardNumber() + "费用:" + moneytmp);
			} else {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step2minutes));
				if (hours * step2Price > nightCarMax) {
					moneytmp += nightCarMax;
				} else {
					moneytmp += hours * step2Price;
				}
				logger.info("计费-车牌号:" + charge.getCardNumber() + "费用:" + moneytmp);
			}

			money += moneytmp;
			logger.info("计费**车牌号:" + charge.getCardNumber() + "累积费用:" + money);
		}
		tempMoney = money;
		if (charge.getDiscountType() == 1) {// 全免优惠券
			tempMoney = 0;
		} else if (charge.getDiscountType() == 2) {// 金额优惠券
			tempMoney = money - charge.getDiscount() > 0 ? money - charge.getDiscount() : 0;
		} else if (charge.getDiscountType() == 3) {// 固定金额优惠券
			tempMoney = charge.getDiscount();
		}
		charge.setPaidMoney(money);
		charge.setPaidCompleted(true);
		charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
		charge.setChargeMoney(tempMoney);
		logger.info("众彩物流:" + charge.toString());
		return charge;
	}

	@Override
	public List<PosChargeData> getByCardNumberAndPark(String cardNumber, Integer parkId) {
		// TODO Auto-generated method stub
		return chargeDao.getByCardNumberAndPark(cardNumber, parkId);
	}

	@Override
	public Map<String, Object> getParkChargeCountByDay(int parkId, String day) {
		// TODO Auto-generated method stub

		Park park = parkService.getParkById(parkId);
		String parkName = park.getName();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date parsedStartDay = null;
		try {
			parsedStartDay = sdf.parse(day + " 00:00:00");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		Date parsedEndDay = null;
		try {
			parsedEndDay = sdf.parse(day + " 23:59:59");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		List<PosChargeData> posChargeDatas = selectPosdataByParkAndRange(parsedStartDay, parsedEndDay, parkId);
		Map<String, Object> retmap = new HashMap<>();
		int outcount = 0;
		if (posChargeDatas.isEmpty()) {
			retmap.put("in", 0);
			retmap.put("out", 0);
		} else {
			for (PosChargeData posChargeData : posChargeDatas) {
				if (posChargeData.getExitDate() != null) {
					outcount += 1;
				}
			}
			retmap.put("in", posChargeDatas.size());
			retmap.put("out", outcount);
		}

		return retmap;
	}

	@Override
	public List<PosChargeData> getDebtWithData(String cardNumber, List<Parktoalipark> parktoaliparks,
			List<Monthuser> monthusers, Park park, Boolean isMultiFeeCtriterion, int carType, boolean isQuery,
			String expirationTime) throws Exception {
		List<PosChargeData> charges = new ArrayList<>();
		logger.info(cardNumber + "进入[getDebtWithData]开始处理订单信息");
		String redisId = jedisClient.get("P-" + park.getId() + "-" + cardNumber);
		try {

			if (redisId != null) {
				PosChargeData posChargeData = chargeDao.getById(Integer.parseInt(redisId));
				if (posChargeData != null) {

					if (posChargeData.getParkDesc().contains("包月车")) {
						monthusers = monthUserDao.getByCarnumberAndPark(cardNumber, park.getId());
						if (posChargeData != null && (!StringUtils.isEmpty(expirationTime))) {
							Date tempTime = null;
							try {
								tempTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(expirationTime);
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							if ((posChargeData.getEntranceDate().compareTo(tempTime) < 0)
									&& (tempTime.compareTo(new Date()) < 0)) {
								posChargeData.setValidTimeStart(expirationTime);
							}
						}
					}

					// 时间优惠券

					if (Integer.valueOf(posChargeData.getDiscountType()) == 4) {
						SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
						Calendar nowTime = Calendar.getInstance();
						if (StringUtils.isBlank(posChargeData.getValidTimeStart())) {
							nowTime.setTime(posChargeData.getEntranceDate());
						} else {
							nowTime.setTime(new SimpleDateFormat().parse(posChargeData.getValidTimeStart()));
						}
						nowTime.add(Calendar.MINUTE, posChargeData.getDiscount().intValue());
						posChargeData.setValidTimeStart(sdf.format(nowTime.getTime()));
						logger.info(posChargeData.getCardNumber() + "修改计费时间为" + posChargeData.getValidTimeStart());
					}
					logger.info(cardNumber + "redis获取订单信息:poschargedataId:" + redisId);
					charges.add(posChargeData);
					if (charges.get(0).isPaidCompleted()) {// 非现金支付的情况，支付宝/微信支付的情况
						logger.info(cardNumber + "redis获取订单信息但是订单已经完成，即已经通过非现金支付");
						charges.clear();
						return charges;
					}
				}

			} else {
				logger.info(cardNumber + "未在redis中发现记录,查询键" + "P-" + park.getId() + "-" + cardNumber);
				// charges = chargeDao.getDebtWithParkId(cardNumber,
				// park.getId());//redis没有记录，则全表查数据库，时间很慢
			}
		} catch (Exception e) {
			logger.info(cardNumber + "查询redis记录发生异常");
			logger.info(e.getMessage());
			// charges = chargeDao.getDebtWithParkId(cardNumber, park.getId());
			// jedisClient.del(redisId);
			return charges;
		}

		logger.info(cardNumber + "取得未付款记录" + charges.size() + "条");
		List<PosChargeData> tmPosChargeDatas = new ArrayList<>();
		if (charges.isEmpty()) {
			return charges;
		}
		for (PosChargeData charge : charges) {
			// logger.info(charge.getCardNumber()+"-入场-"+Utility.formatDatetime(charge.getEntranceDate())+"-"+charge.getParkDesc());
			if (charge.getExitDate() == null) {
				tmPosChargeDatas.add(charge);
			}

		}

		// if (parktoaliparks!=null&&!parktoaliparks.isEmpty() &&
		// !tmPosChargeDatas.isEmpty()&&tmPosChargeDatas.get(0).getExitDate() == null) {
		// // 信息录入支付宝
		// try {
		// Parktoalipark parktoalipark = parktoaliparks.get(0);
		// Map<String, String> argstoali = new HashMap<>();
		// argstoali.put("parking_id", parktoalipark.getAliparkingid());
		// argstoali.put("car_number", cardNumber);
		// argstoali.put("out_time", new SimpleDateFormat("yyyy-MM-dd
		// HH:mm:ss").format(new Date()));
		// ActiveMqService.SendWithQueueName(JsonUtils.objectToJson(argstoali),
		// "aliExitInfo");
		//
		//
		// List<Parknoticeauthority> parkcarauthorities =
		// parkNoticeAuthorityService.getByParkId(tmPosChargeDatas.get(0).getParkId());
		// if (!parkcarauthorities.isEmpty() && (parkcarauthorities.get(0)).getAlipay()
		// == true){
		// Map<String, String> argstoali2 = new HashMap<>();
		// argstoali2.put("parking_id", "PI1501317472942184881");
		// argstoali2.put("car_number", cardNumber);
		// argstoali2.put("out_time", new SimpleDateFormat("yyyy-MM-dd
		// HH:mm:ss").format(new Date()));
		// ActiveMqService.SendWithQueueName(JsonUtils.objectToJson(argstoali2),
		// "aliExitInfo");
		// }
		// } catch (Exception e) {
		// // TODO: handle exception
		// }
		// }

		// this.calExpenseMulti(tmPosChargeDatas.get(0), new Date(),
		// false,isMultiFeeCtriterion,carType);
		FeeCriterion criterion = null;
		if (isMultiFeeCtriterion) {
			logger.info(cardNumber + "属于多计费标准，则查询多计费标准");
			List<Feecriteriontopark> feecriteriontoparks = feecriterionToParkService.getByParkAndType(park.getId(),
					carType);
			if (!feecriteriontoparks.isEmpty()) {
				criterion = criterionService.getById(feecriteriontoparks.get(0).getCriterionid());
			}
		} else {
			logger.info(cardNumber + "不属于多计费标准");
			criterion = criterionService.getById(park.getFeeCriterionId());
		}
		if (criterion == null) {
			criterion = criterionService.getById(park.getFeeCriterionId());
		}

		if (!tmPosChargeDatas.isEmpty()) {

			// 12小时内免费时间设置
			try {
				if (park.getDescription().contains("12小时内免费")
						&& !StringUtils.isEmpty(tmPosChargeDatas.get(0).getOther2())) {
					PosChargeData lastPosChargeData = getById(Integer.valueOf(tmPosChargeDatas.get(0).getOther2()));
					logger.info(cardNumber + "获取12小时免费上次id" + lastPosChargeData.getId());
					Date newEntranceDate = tmPosChargeDatas.get(0).getEntranceDate();

					if (lastPosChargeData.getChargeMoney() > 0.1 && lastPosChargeData.isPaidCompleted()) {
						logger.info(lastPosChargeData.getCardNumber() + "上次完成支付,进行12小时内时间处理");
						newEntranceDate = new Date(lastPosChargeData.getEntranceDate().getTime() + 12 * 60 * 60 * 1000);
					}
					if (!isQuery && lastPosChargeData.getChargeMoney() < 0.1 && lastPosChargeData.isPaidCompleted()) {
						logger.info(cardNumber + "上次收费为0,此次设置12小时内免费redis");

						jedisClient.set("P-" + park.getId() + "-12-" + cardNumber,
								String.valueOf(tmPosChargeDatas.get(0).getId()), 43200);
					}
					if (newEntranceDate.getTime() > System.currentTimeMillis()) {
						tmPosChargeDatas.get(0).setPaidCompleted(true);
						tmPosChargeDatas.get(0)
								.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
						tmPosChargeDatas.get(0).setRejectReason("12小时内免费");
						tmPosChargeDatas.get(0).setExitDate1(new Date());
						if (!isQuery) {
							update(tmPosChargeDatas.get(0));
						}
						return tmPosChargeDatas;
					}
					// 必须是可减免状态
					if (newEntranceDate.getTime() > tmPosChargeDatas.get(0).getEntranceDate().getTime()) {
						tmPosChargeDatas.get(0).setEntranceDate1(newEntranceDate);
						tmPosChargeDatas.get(0)
								.setOther2("12小时内免费,修正入场计费时间从"
										+ Utility.formatDatetime(tmPosChargeDatas.get(0).getEntranceDate()) + "--"
										+ Utility.formatDatetime(newEntranceDate));
					}

				}
			} catch (Exception e) {
			}
			this.calExpensewithData(tmPosChargeDatas.get(0), new Date(), isQuery, monthusers, park, criterion);
			if (!isQuery) {
				try {
					// jedisClient.del("P-" + park.getId() + "-" + cardNumber);
					jedisClient.del("query" + cardNumber);
				} catch (Exception e) {
				}
			}
		}
		int tmpint = 0;
		for (PosChargeData tmpcharge : tmPosChargeDatas) {
			tmpint++;
			if (tmpint > 1) {
				logger.info(cardNumber + "开始平台清场---> 被清场数据为poschargeDataID：" + tmpcharge.getId());
				tmpcharge.setChargeMoney(0);
				tmpcharge.setExitDate1(tmpcharge.getEntranceDate());
				tmpcharge.setPaidCompleted(true);
				tmpcharge.setPaidMoney(0);
				tmpcharge.setRejectReason("平台清场");
				update(tmpcharge);
			}
		}
		logger.info(cardNumber + "<-----离开[getDebtWithData]开始处理订单信息");
		// 12小时不收费设置
		if (!tmPosChargeDatas.isEmpty() && park.getDescription().contains("12小时内免费")) {
			logger.info(cardNumber + "12小时内不收费,设置redis的值");
			PosChargeData posChargeData = tmPosChargeDatas.get(0);

			if (!isQuery) {
				if (posChargeData.getExitDate().getTime() - posChargeData.getEntranceDate().getTime() < 43200 * 1000) {
					jedisClient.set("P-" + park.getId() + "-12-" + cardNumber, String.valueOf(posChargeData.getId()),
							43200);
				}

			}
		}

		return tmPosChargeDatas;
	}

	@Override
	public List<PosChargeData> getDebtWithDataV2(String cardNumber, List<Parktoalipark> parktoaliparks,
			List<Monthuser> monthusers, Park park, Boolean isMultiFeeCtriterion, int carType, boolean isQuery,
			String expirationTime) {
		List<PosChargeData> charges = new ArrayList<>();
		logger.info(cardNumber + "----->进入[getDebtWithDataV2]开始处理订单信息");
		String redisId = jedisClient.get("P-" + park.getId() + "-" + cardNumber);
		try {

			if (redisId != null) {
				logger.info(cardNumber + "redis获取订单信息:poschargedataId:" + redisId);
				PosChargeData charge = chargeDao.getById(Integer.parseInt(redisId));
				logger.info(charge);
				if (charge != null) {
					if (charge.getParkDesc().contains("包月车")) {
						logger.info("包月车");
						monthusers = monthUserDao.getByCarnumberAndPark(cardNumber, park.getId());
						if (charge != null && (!StringUtils.isEmpty(expirationTime))) {
							Date tempTime = null;
							try {
								tempTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(expirationTime);
							} catch (ParseException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							logger.info("入场时间：" + charge.getEntranceDate());
							if ((charge.getEntranceDate().compareTo(tempTime) < 0)
									&& (tempTime.compareTo(new Date()) < 0)) {
								logger.info("修改入场时间");
								try {
									charge.setEntranceDate(expirationTime);
								} catch (ParseException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
						}
					}
					charges.add(charge);
					if (charges.get(0).isPaidCompleted()) {// 非现金支付的情况，支付宝/微信支付的情况
						logger.info(cardNumber + "redis获取订单信息但是订单已经完成，即已经通过非现金支付");
						charges.clear();
						return charges;
					}
				}
			} else {
				logger.info(cardNumber + "未在redis中发现记录,查询键" + "P-" + park.getId() + "-" + cardNumber);
				// charges = chargeDao.getDebtWithParkId(cardNumber,
				// park.getId());//redis没有记录，则全表查数据库，时间很慢
			}
		} catch (Exception e) {
			logger.info(cardNumber + "查询redis记录发生异常");
			// charges = chargeDao.getDebtWithParkId(cardNumber, park.getId());
			return charges;
		}

		logger.info(cardNumber + "取得未付款记录" + charges.size() + "条");
		List<PosChargeData> tmPosChargeDatas = new ArrayList<>();
		if (charges.isEmpty()) {
			return charges;
		}
		for (PosChargeData charge : charges) {
			// logger.info(charge.getCardNumber()+"-入场-"+Utility.formatDatetime(charge.getEntranceDate())+"-"+charge.getParkDesc());
			if (charge.getExitDate() == null) {
				tmPosChargeDatas.add(charge);
			}

		}

		// if (parktoaliparks!=null&&!parktoaliparks.isEmpty() &&
		// !tmPosChargeDatas.isEmpty()&&tmPosChargeDatas.get(0).getExitDate() == null) {
		// // 信息录入支付宝
		// try {
		// Parktoalipark parktoalipark = parktoaliparks.get(0);
		// Map<String, String> argstoali = new HashMap<>();
		// argstoali.put("parking_id", parktoalipark.getAliparkingid());
		// argstoali.put("car_number", cardNumber);
		// argstoali.put("out_time", new SimpleDateFormat("yyyy-MM-dd
		// HH:mm:ss").format(new Date()));
		// ActiveMqService.SendWithQueueName(JsonUtils.objectToJson(argstoali),
		// "aliExitInfo");
		//
		//
		// List<Parknoticeauthority> parkcarauthorities =
		// parkNoticeAuthorityService.getByParkId(tmPosChargeDatas.get(0).getParkId());
		// if (!parkcarauthorities.isEmpty() && (parkcarauthorities.get(0)).getAlipay()
		// == true){
		// Map<String, String> argstoali2 = new HashMap<>();
		// argstoali2.put("parking_id", "PI1501317472942184881");
		// argstoali2.put("car_number", cardNumber);
		// argstoali2.put("out_time", new SimpleDateFormat("yyyy-MM-dd
		// HH:mm:ss").format(new Date()));
		// ActiveMqService.SendWithQueueName(JsonUtils.objectToJson(argstoali2),
		// "aliExitInfo");
		// }
		// } catch (Exception e) {
		// // TODO: handle exception
		// }
		// }

		// this.calExpenseMulti(tmPosChargeDatas.get(0), new Date(),
		// false,isMultiFeeCtriterion,carType);
		FeeCriterion criterion = null;
		if (isMultiFeeCtriterion) {
			logger.info(cardNumber + "属于多计费标准，则查询多计费标准");
			List<Feecriteriontopark> feecriteriontoparks = feecriterionToParkService.getByParkAndType(park.getId(),
					carType);
			if (!feecriteriontoparks.isEmpty()) {
				criterion = criterionService.getById(feecriteriontoparks.get(0).getCriterionid());
			}
		} else {
			logger.info(cardNumber + "不属于多计费标准");
			criterion = criterionService.getById(park.getFeeCriterionId());
		}
		if (criterion == null) {
			criterion = criterionService.getById(park.getFeeCriterionId());
		}
		if (!tmPosChargeDatas.isEmpty()) {
			try {
				this.calExpensewithData(tmPosChargeDatas.get(0), new Date(), isQuery, monthusers, park, criterion);
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			if (!isQuery) {
				try {
					jedisClient.del("P-" + park.getId() + "-" + cardNumber);
					jedisClient.del("query" + cardNumber);
				} catch (Exception e) {
					// TODO: handle exception
				}
			}

		}
		int tmpint = 0;
		for (PosChargeData tmpcharge : tmPosChargeDatas) {
			tmpint++;
			if (tmpint > 1) {
				logger.info(cardNumber + "开始平台清场---> 被清场数据为poschargeDataID：" + tmpcharge.getId());
				tmpcharge.setChargeMoney(0);
				tmpcharge.setExitDate1(tmpcharge.getEntranceDate());
				tmpcharge.setPaidCompleted(true);
				tmpcharge.setPaidMoney(0);
				tmpcharge.setRejectReason("平台清场");
				update(tmpcharge);
			}
		}
		logger.info(cardNumber + "<-----离开[getDebtWithDataV2]开始处理订单信息");
		return tmPosChargeDatas;
	}

	@Override
	public void calExpenseSmallCarWithData(PosChargeData charge, Date exitDate, Boolean isQuery, Park park,
			FeeCriterion criterion) {
		logger.info(charge.getCardNumber() + "进入小车计费,此费用计费不要提前剔除免费时段,会自己处理");
		charge.setExitDate1(exitDate);
		double expense = 0;
		if (criterion.getIsonetimeexpense() != null && criterion.getIsonetimeexpense().intValue() == 1) {
			charge.setIsOneTimeExpense(1);
		}
		float diffMin = (float) Math
				.ceil((charge.getExitDate().getTime() - charge.getEntranceDate().getTime()) / (1000 * 60f));
		if (charge.getIsOneTimeExpense() == 1 && diffMin >= criterion.getFreemins()) {
			expense = criterion.getOnetimeexpense();
			if (criterion.getId() > 29) {
				expense = criterion.getStep3price();
			}
			logger.info(charge.getCardNumber() + "夜间计费,时长" + diffMin + "费用" + expense);
		} else {

			float firstHour = criterion.getStep1capacity();

			if (diffMin > criterion.getFreemins()) {
				if (diffMin <= firstHour) {
					double intervals = Math
							.ceil((diffMin - criterion.getFreemins()) / criterion.getTimeoutpriceinterval());
					expense = intervals * criterion.getStep1price();
					logger.info(charge.getCardNumber() + "第一阶段,时长" + intervals + "费用" + expense);
				} else {
					double intervals1 = Math
							.ceil((firstHour - criterion.getFreemins()) / criterion.getTimeoutpriceinterval());
					expense = intervals1 * criterion.getStep1price();
					double intervals2 = Math.ceil((diffMin - firstHour) / (criterion.getTimeoutpriceinterval()));
					expense += intervals2 * criterion.getStep2price();
					logger.info(charge.getCardNumber() + "第二阶段,时长" + intervals2 + "费用"
							+ intervals2 * criterion.getStep2price());
				}
			}
		}
		if (expense > criterion.getMaxexpense()) {
			expense = criterion.getMaxexpense();
			logger.info(charge.getCardNumber() + "超过最高计费费用,修正为" + expense);
		}

		charge.setChargeMoney(Double.valueOf(df.format(expense + charge.getChargeMoney())));

		logger.info(charge.getCardNumber() + "-" + Utility.formatDatetime(charge.getEntranceDate()) + "-"
				+ Utility.formatDatetime(exitDate) + "calExpenseSmallCarWithData费用" + charge.getChargeMoney());
	}

	public void calExpenseTaizhouGonghang(PosChargeData charge, Date exitDate, Boolean isQuery, Park park,
			FeeCriterion criterion) {

		charge.setExitDate1(exitDate);
		double expense = 0;
		if (criterion.getIsonetimeexpense() != null && criterion.getIsonetimeexpense().intValue() == 1) {
			charge.setIsOneTimeExpense(1);
		}
		float diffMin = (float) Math
				.ceil((charge.getExitDate().getTime() - charge.getEntranceDate().getTime()) / (1000 * 60f));
		if (charge.getIsOneTimeExpense() == 1 && diffMin >= criterion.getFreemins()) {
			expense = criterion.getOnetimeexpense();
			if (criterion.getId() > 29) {
				expense = criterion.getStep3price();
			}
			logger.info(charge.getCardNumber() + "夜间计费" + expense);
		} else {

			float firstHour = criterion.getStep1capacity();
			if (diffMin <= firstHour) {
				double intervals = Math.ceil((diffMin) / 120);
				expense = intervals * criterion.getStep1price();
				logger.info(charge.getCardNumber() + "第一阶段,时长" + intervals + "费用" + expense);
			} else {
				double intervals1 = Math.ceil((firstHour) / 120);
				expense = intervals1 * criterion.getStep1price();
				double intervals2 = Math.ceil((diffMin - firstHour) / 30f);

				expense += intervals2 * criterion.getStep2price();
				logger.info(charge.getCardNumber() + "第二阶段,时长" + intervals2 + "费用"
						+ intervals2 * criterion.getStep2price());
			}

		}
		if (expense > criterion.getMaxexpense()) {
			expense = criterion.getMaxexpense();
			logger.info(charge.getCardNumber() + "超过最高计费费用,修正为" + expense);
		}

		charge.setChargeMoney(Double.valueOf(df.format(expense + charge.getChargeMoney())));

		logger.info(charge.getCardNumber() + " " + Utility.formatDatetime(charge.getEntranceDate()) + " "
				+ Utility.formatDatetime(exitDate) + "calExpenseSmallCarWithData费用" + charge.getChargeMoney());
	}

	@Override
	public void calExpenseLargeCarWithData(PosChargeData charge, Date exitDate, Boolean isQuery, Park park,
			FeeCriterion criterion) {
		logger.info(charge.getCardNumber() + "进入大车计费,此计费在内部做了免费时段计费剔除工作");
		int rate = 1;
		if (StringUtils.isNotBlank(criterion.getOther())) {
			String ctrOther = criterion.getOther();
			if (ctrOther.contains("MaxRateToSmallCar")) {
				rate = 2;
				logger.info(charge.getCardNumber() + "费率改为2");
			}
		}

		if (criterion.getIsonetimeexpense() != null && criterion.getIsonetimeexpense().intValue() == 1) {
			charge.setIsOneTimeExpense(1);
		}
		charge.setExitDate1(exitDate);
		double expense = 0;
		float diffMin = (charge.getExitDate().getTime() - charge.getEntranceDate().getTime()) / (1000 * 60f);
		if (charge.getIsOneTimeExpense() == 1 && diffMin >= criterion.getFreemins()) {
			expense = criterion.getOnetimeexpense();
			// 如果计费标准的id超过29 从计费标准的第三阶段来处理
			if (criterion.getId() > 29) {
				expense = criterion.getStep3price();
			}
			logger.info(charge.getCardNumber() + "夜间计费,时长" + diffMin + "费用" + expense);
		} else {
			float firstHour = criterion.getStep1capacity();
			if (diffMin > criterion.getFreemins()) {
				if (diffMin <= firstHour) {
					double intervals = Math
							.ceil((diffMin - criterion.getFreemins()) / criterion.getTimeoutpriceinterval());
					expense = intervals * criterion.getStep1pricelarge();
					logger.info(charge.getCardNumber() + "第一阶段,时长" + intervals + "费用" + expense);
				} else {
					double intervals1 = Math
							.ceil((firstHour - criterion.getFreemins()) / criterion.getTimeoutpriceinterval());
					expense = intervals1 * criterion.getStep1pricelarge();
					double intervals2 = Math
							.ceil((diffMin - firstHour) / ((float) criterion.getTimeoutpriceinterval()));

					expense += intervals2 * criterion.getStep2pricelarge();
					logger.info(charge.getCardNumber() + "第二阶段,时长" + intervals2 + "费用"
							+ intervals2 * criterion.getStep2price());
				}
			}
		}
		if (expense > criterion.getMaxexpense() * rate) {
			expense = criterion.getMaxexpense() * rate;
			logger.info(charge.getCardNumber() + "超过最高计费费用,修正为" + expense);
		}

		charge.setChargeMoney(Double.valueOf(df.format(expense + charge.getChargeMoney())));

		logger.info(charge.getCardNumber() + " 入场时间" + Utility.formatDatetime(charge.getEntranceDate()) + "出场时间"
				+ Utility.formatDatetime(exitDate) + "calExpenseLargeCarWithData得到最后费用" + charge.getChargeMoney());
	}

	@Override
	public List<PosChargeData> getLastRecordWithPark(String carNumber, int count, int parkId) {
		String idString = jedisClient.get("mobilepay" + parkId + carNumber);
		if (idString != null) {
			List<PosChargeData> posChargeDatas = new ArrayList<PosChargeData>();
			posChargeDatas.add(chargeDao.getById(Integer.parseInt(idString)));
			return posChargeDatas;
		}
		// TODO Auto-generated method stub
		return chargeDao.getLastRecordWithPark(carNumber, count, parkId);
//		List<PosChargeData> posChargeDatas=new ArrayList<>();
//		String poschargeId=jedisClient.get(carNumber+"-"+parkId+"-mobilepay");
//		if (poschargeId!=null) {
//			posChargeDatas.add(getById(Integer.parseInt(poschargeId)));
//		}
//		return posChargeDatas;
	}

	@Override
	public void calExpensewithData(PosChargeData charge, Date exitDate, Boolean isQuery, List<Monthuser> monthusers,
			Park park, FeeCriterion criterion) throws Exception {
		Boolean isMonthUser = false;
		Boolean isRealMonthUser = false;
		Monthuser monthuserUse = new Monthuser();

		for (Monthuser monthuser : monthusers) {
			if (monthuser.getType() == 0) {
				Long diff = (monthuser.getEndtime().getTime() - (new Date()).getTime());
				if (diff > 0 && monthuser.getPlatenumber().trim().contains(charge.getCardNumber())) {
					isMonthUser = true;
					monthuserUse = monthuser;
					isRealMonthUser = true;
					break;
				}
			}
		}
		Boolean isMultiCarsOneCarport = false;
		if (park.getDescription() != null && park.getDescription().contains("一位多车")) {
			isMultiCarsOneCarport = true;
		}
		logger.info(charge.getCardNumber() + "-是否月卡:" + isRealMonthUser + "-计费标准:" + criterion.getName());
		if (isMultiCarsOneCarport && isRealMonthUser && monthuserUse.getPlatecolor() != null
				&& monthuserUse.getPlatecolor().equals("包月转临停")) {
			isRealMonthUser = false;
			monthuserUse.setPlatecolor("出场完结");
			monthUserService.updateByPrimaryKeySelective(monthuserUse);
		}
		// 包月转临停
		if (charge.getParkDesc().contains("包月转临停")) {
			isRealMonthUser = false;
		}

		if (charge.getParkDesc().contains("临停车")) {
			isRealMonthUser = false;
		}
		if (isRealMonthUser) {
			logger.info(charge.getCardNumber() + "月卡结算完毕!");
			charge.setChargeMoney(0);
			charge.setUnPaidMoney(0);
			charge.setExitDate1(exitDate);
			charge.setPaidCompleted(true);
			charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
			if (!isQuery) {
				if (isMultiCarsOneCarport && monthuserUse.getPlatecolor() != null
						&& monthuserUse.getPlatecolor().equals("多车包月入场")) {
					monthuserUse.setPlatecolor("出场完结");
					// List<Monthuser> monthuserss =
					// monthUserService.getByUsernameAndPark(monthuserUse.getOwner(),
					// monthuserUse.getParkid());

					monthUserService.updateByPrimaryKeySelective(monthuserUse);
				}
				this.update(charge);
			}
			return;
		}
		if (!isRealMonthUser && charge.getParkDesc().contains("包月车")) {
			charge.setParkDesc(park.getName() + "---临停");
		}
		// 计费标准类型：0-普通分时段计费 1-按次计费 2-白天晚上模板 4-24小时计费标准
		if (criterion.getType() == 2 && charge.getParkId() == 282) { // 双龙夹岗产业园
			logger.info(charge.getCardNumber() + "进入夹岗计费标准计算");
			calJiagang(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			logger.info(charge.getCardNumber() + "离开夹岗计费标准计算");
			return;
		}
		if (criterion.getType() == 2) {// 2-白天晚上计费模板
			logger.info(charge.getCardNumber() + "进入白天晚上计费标准计算");
			newFeeCalcExpense2(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {

				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			logger.info(charge.getCardNumber() + "离开白天晚上计费标准计算");
			return;
		}
		if (criterion.getType() == 1) {// 按次
			newFeeCalcExpense1(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}

		if (criterion.getType() == 4) {// 24小时
			logger.info(charge.getCardNumber() + "进入24小时制计费标准计算");
			newFeeCalcExpense4(charge, criterion, exitDate, isQuery, park);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			logger.info(charge.getCardNumber() + "离开24小时制计费标准计算");
			return;
		}

		if (criterion.getType() == 101) {// 重庆永川定制
			logger.info(charge.getCardNumber() + "进入永川定制计费标准计算");
			chongqingyongchuanjifei(charge, criterion, exitDate, isQuery, park, monthusers);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			logger.info(charge.getCardNumber() + "离开永川定制计费标准计算");

			return;
		}
		if (criterion.getType() == 102) {// 台州市工行定制
			logger.info(charge.getCardNumber() + "进入泰州工行定制计费标准计算");

			taizhougonghang(charge, criterion, exitDate, isQuery, park, monthusers);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			logger.info(charge.getCardNumber() + "离开泰州工行定制计费标准计算");

			return;
		}
		// 和县计费标准定制
		if (criterion.getType() == 141) {
			hexiananliangxuefu(charge, criterion, exitDate, isQuery, park);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}
		// 三门峡计费标准
		if (criterion.getType() == 510) {
			calCommonPark(charge, exitDate, isQuery, isRealMonthUser, park, criterion);
			if (exitDate.getTime() - charge.getEntranceDate().getTime() <= 12 * 60 * 60 * 1000) {
				if (charge.getChargeMoney() > 10) {
					charge.setChargeMoney(10);
					logger.info(charge.getCardNumber() + "12小时内费用超过10元 修正为10元");
				}
			}
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}
		// 腾飞大厦
		if (criterion.getType() == 508) {
			tengfeidasha(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}
		// 航运中心
		if (criterion.getType() == 568) {
			hangyunzhongxin(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}

		// 江苏肿瘤医院
		if (criterion.getType() == 509) {
			zhongliuyiyuan(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}

		// 东云街主
		if (criterion.getType() == 513) {
			FeeAddService.dongyunjiezhu(charge, criterion, exitDate, isQuery, park);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}
		// 东云街48
		if (criterion.getType() == 514) {
			FeeAddService.dongyunjie48(charge, criterion, exitDate, isQuery, park);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}
		// 东云街新计费标准
		if (criterion.getType() == 515) {
			logger.info(charge.getCardNumber() + "进入东云街新计费标准计算");
			FeeAddService.dongyunjie515(charge, criterion, exitDate, isQuery, park);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}

		// 南京南站
		if (criterion.getType() == 142) {
			logger.info(charge.getCardNumber() + "进入南站定制计费标准计算");

			nanjingNan(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			logger.info(charge.getCardNumber() + "离开定制计费标准计算");

			return;
		}
		// 众彩物流
		if (criterion.getType() == 596) {
			logger.info(charge.getCardNumber() + "进入众彩物流计费标准计算");
			zhongcaiwuliu(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {

				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			logger.info(charge.getCardNumber() + "离开众彩物流计费标准计算");
			return;
		}
		// 三个计费阶段
		if (criterion.getType() == 6) {
			newFeeCalcExpense6(charge, criterion, exitDate, isQuery, park);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}

		// 通用分段计费
		calCommonPark(charge, exitDate, isQuery, isRealMonthUser, park, criterion);
	}

	public PosChargeData tengfeidasha(PosChargeData charge, FeeCriterion criterion, Date exitDate, Boolean isQuery)
			throws ParseException {
		if (exitDate == null) {
			exitDate = new Date();
		}
		charge.setExitDate1(exitDate);

		// 入场免费时间处理
		int freeMinutes = criterion.getFreemins();

		Date entranceDate = new Date(charge.getEntranceDate().getTime() + freeMinutes * 60 * 1000);

		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(entranceDate);
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "8";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		if (entranceDate.getTime() > exitDate.getTime()) {
			charge.setChargeMoney(0);
			return charge;
		}
		double money = 0;

		double step1Price = criterion.getStep1price();
		double step2Price = criterion.getStep3price();
		int step1Minutes = 15;
		int step2minutes = 60;
		step1Minutes = criterion.getTimeoutpriceinterval();
		step2minutes = criterion.getTimeoutpriceinterval2();
		if (charge.getIsLargeCar()) {
			step1Price = criterion.getStep1pricelarge();
			step2Price = criterion.getStep3pricelarge();
		}
		double daymaxfei = 12;
		double nightmaxfei = 6;
		Map<String, String> dates0 = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
		double moneytmp = 0;
		for (String name : dates0.keySet()) {
			logger.info("计费**车牌号:" + charge.getCardNumber() + "时间:" + name + "-" + dates0.get(name));
			Date startDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(name);
			Date endDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(dates0.get(name));
			String startd = name.substring(11, 13);
			if (Integer.parseInt(startd) >= Integer.parseInt(nightEndHour)
					&& Integer.parseInt(startd) < Integer.parseInt(nightStartHour)) {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step1Minutes));
				if (hours * step1Price > daymaxfei) {
					moneytmp += daymaxfei;
				} else {
					moneytmp += hours * step1Price;
				}
				logger.info("计费**车牌号:" + charge.getCardNumber() + "费用:" + hours * step1Price);
			} else {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step2minutes));
				if (hours * step2Price > nightmaxfei) {
					moneytmp += nightmaxfei;
				} else {
					moneytmp += hours * step2Price;
				}
				logger.info("计费**车牌号:" + charge.getCardNumber() + "费用:" + hours * step2Price);
			}
			logger.info("计费**车牌号:" + charge.getCardNumber() + "累积费用:" + moneytmp);
		}
		if (moneytmp > criterion.getMaxexpense()) {
			logger.info(charge.getCardNumber() + "达到一天最大金额" + moneytmp + "to" + criterion.getMaxexpense());
			moneytmp = criterion.getMaxexpense();
		}
		money += moneytmp;

		charge.setChargeMoney(Double.valueOf(df.format(money)));
		return charge;
	}

	public PosChargeData hangyunzhongxin(PosChargeData charge, FeeCriterion criterion, Date exitDate, Boolean isQuery)
			throws ParseException {
		if (exitDate == null) {
			exitDate = new Date();
		}
		charge.setExitDate1(exitDate);

		// 入场免费时间处理
		int freeMinutes = criterion.getFreemins();

		Date entranceDate = new Date(charge.getEntranceDate().getTime() + freeMinutes * 60 * 1000);

		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(entranceDate);
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "8";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		if (entranceDate.getTime() > exitDate.getTime()) {
			charge.setChargeMoney(0);
			return charge;
		}
		double money = 0;

		double step1Price = criterion.getStep1price();
		double step2Price = criterion.getStep3price();
		int step1Minutes = 15;
		int step2minutes = 60;
		step1Minutes = criterion.getTimeoutpriceinterval();
		step2minutes = criterion.getTimeoutpriceinterval2();
		if (charge.getIsLargeCar()) {
			step1Price = criterion.getStep1pricelarge();
			step2Price = criterion.getStep3pricelarge();
		}
		double daymaxfei = 24;
		double nightmaxfei = 6;
		Map<String, String> dates0 = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
		double moneytmp = 0;
		for (String name : dates0.keySet()) {
			logger.info("计费**车牌号:" + charge.getCardNumber() + "时间:" + name + "-" + dates0.get(name));
			Date startDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(name);
			Date endDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(dates0.get(name));
			String startd = name.substring(11, 13);
			if (Integer.parseInt(startd) >= Integer.parseInt(nightEndHour)
					&& Integer.parseInt(startd) < Integer.parseInt(nightStartHour)) {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step1Minutes));
				if (hours * step1Price > daymaxfei) {
					moneytmp += daymaxfei;
				} else {
					moneytmp += hours * step1Price;
				}
				logger.info("计费**车牌号:" + charge.getCardNumber() + "费用:" + hours * step1Price);
			} else {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step2minutes));
				if (hours * step2Price > nightmaxfei) {
					moneytmp += nightmaxfei;
				} else {
					moneytmp += hours * step2Price;
				}
				logger.info("计费**车牌号:" + charge.getCardNumber() + "费用:" + hours * step2Price);
			}
			logger.info("计费**车牌号:" + charge.getCardNumber() + "累积费用:" + moneytmp);
		}
		if (moneytmp > criterion.getMaxexpense()) {
			logger.info(charge.getCardNumber() + "达到一天最大金额" + moneytmp + "to" + criterion.getMaxexpense());
			moneytmp = criterion.getMaxexpense();
		}
		money += moneytmp;

		charge.setChargeMoney(Double.valueOf(df.format(money)));
		return charge;
	}

	public PosChargeData zhongliuyiyuan(PosChargeData charge, FeeCriterion criterion, Date exitDate, Boolean isQuery)
			throws ParseException {
		if (exitDate == null) {
			exitDate = new Date();
		}
		charge.setExitDate1(exitDate);

		// 入场免费时间处理
		int freeMinutes = criterion.getFreemins();

		Date entranceDate = new Date(charge.getEntranceDate().getTime() + freeMinutes * 60 * 1000);

		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(entranceDate);
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "8";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		if (entranceDate.getTime() > exitDate.getTime()) {
			charge.setChargeMoney(0);
			return charge;
		}
		double money = 0;

		double step1Price = criterion.getStep1price();
		double step2Price = criterion.getStep3price();
		int step1Minutes = 15;
		int step2minutes = 60;
		step1Minutes = criterion.getTimeoutpriceinterval();
		step2minutes = criterion.getTimeoutpriceinterval2();
		if (charge.getIsLargeCar()) {
			step1Price = criterion.getStep1pricelarge();
			step2Price = criterion.getStep3pricelarge();
		}
		double daymaxfei = criterion.getMaxexpense() - 6;
		double nightmaxfei = 6;

		Map<String, String> dates0 = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
		double moneytmp = 0;
		for (String name : dates0.keySet()) {
			logger.info("计费**车牌号:" + charge.getCardNumber() + "时间:" + name + "-" + dates0.get(name));
			Date startDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(name);
			Date endDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(dates0.get(name));
			String startd = name.substring(11, 13);
			if (Integer.parseInt(startd) >= Integer.parseInt(nightEndHour)
					&& Integer.parseInt(startd) < Integer.parseInt(nightStartHour)) {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step1Minutes));
				if (hours * step1Price > daymaxfei) {
					moneytmp += daymaxfei;
				} else {
					moneytmp += hours * step1Price;
				}
				logger.info("计费**车牌号:" + charge.getCardNumber() + "费用:" + hours * step1Price);
			} else {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (1000 * 60 * step2minutes));
				if (hours * step2Price > nightmaxfei) {
					moneytmp += nightmaxfei;
				} else {
					moneytmp += hours * step2Price;
				}
				logger.info("计费**车牌号:" + charge.getCardNumber() + "费用:" + hours * step2Price);
			}
			logger.info("计费**车牌号:" + charge.getCardNumber() + "累积费用:" + moneytmp);
		}

		money += moneytmp;

		charge.setChargeMoney(Double.valueOf(df.format(money)));
		return charge;
	}

	public void calmaxday(PosChargeData charge, FeeCriterion criterion, Date exitDate, Boolean isQuery, Park park) {
		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(charge.getEntranceDate());
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		Map<String, String> dateDay = formatTime.format(startTime, endTime, "24", "00");
		String nightStartHour = "20";
		String nightEndHour = "07";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		int isOneTimeExpense = charge.getIsOneTimeExpense();
		for (String keyString : dateDay.keySet()) {

		}
	}

	//
	private void newFeeCalcExpense6(PosChargeData charge, FeeCriterion criterion, Date exitDate, Boolean isQuery,
			Park park) {
		// TODO Auto-generated method stub
		Date enterDate = charge.getEntranceDate();
		Date enterDateNew = new Date(enterDate.getTime() + criterion.getFreemins() * 1000 * 60);
		long diff = (exitDate.getTime() - enterDateNew.getTime()) / (1000 * 60);
		if (diff <= 0) {
			charge.setChargeMoney(0);
			return;
		}
		int leftMinuts = (int) (diff % (60 * 24));
		int days = (int) (diff / (60 * 24));
		double money = days * criterion.getMaxexpense();
		Date newEnterTime = new Date(exitDate.getTime() - leftMinuts * 1000 * 60);
		// 前三小时免费，3-5小时5元，5-12小时10元，12-24小时20元
		if (diff <= criterion.getStep1capacity() && diff > 0) {
			charge.setChargeMoney(criterion.getStep1price());
		}
		if (diff > criterion.getStep1capacity() && diff <= criterion.getStep2capacity()) {
			charge.setChargeMoney(criterion.getStep2price());
		}
		if (diff > (criterion.getFreemins() + criterion.getStep1capacity() + criterion.getStep2capacity())) {
			charge.setChargeMoney(criterion.getOnetimeexpense());
		}
	}

	@Override
	public PosChargeData newFeeCalcExpenseWithData(PosChargeData charge, Date exitDate, Boolean isQuery, Park park,
			FeeCriterion criterion) throws Exception {
		if (exitDate == null) {
			exitDate = new Date();
		}
		charge.setExitDate1(exitDate);
		// 入场免费时间处理
		int freeMinutes = criterion.getFreemins();
		Date entranceDate = new Date(charge.getEntranceDate().getTime() + freeMinutes * 60 * 1000);
		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(entranceDate);
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "8";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		if (entranceDate.getTime() > exitDate.getTime()) {
			charge.setChargeMoney(0);
			return charge;
		}
		Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
		double money = 0;
		double step1Price = criterion.getStep1price();
		double step2Price = criterion.getStep2price();
		int step1Minutes = 15;
		int step2minutes = 60;
		if (charge.getIsLargeCar()) {
			step1Price = criterion.getStep1pricelarge();
			step2Price = criterion.getStep2pricelarge();
		}
		for (String name : dates.keySet()) {
			logger.info("计费**车牌号:" + charge.getCardNumber() + "时间:" + name + "-" + dates.get(name));
			Date startDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(name);
			Date endDate = new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name));
			String startd = name.substring(11, 13);
			if (Integer.parseInt(startd) >= Integer.parseInt(nightEndHour)
					&& Integer.parseInt(startd) < Integer.parseInt(nightStartHour)) {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (float) (1000 * 60 * step1Minutes));
				money += hours * step1Price;
			} else {
				long diffs = endDate.getTime() - startDate.getTime();
				double hours = Math.ceil((double) diffs / (float) (1000 * 60 * step2minutes));
				money += hours * step2Price;
			}
			logger.info("计费**车牌号:" + charge.getCardNumber() + "费用:" + money);
		}
		charge.setChargeMoney(money);
		return charge;
	}

	@Override
	public Map<String, Object> selectPosdataSumByParkAndRange(Date startDay, Date endDay, int parkId) {
		// TODO Auto-generated method stub
		return chargeDao.selectPosdataSumByParkAndRange(startDay, endDay, parkId);
	}

	@Override
	public Map<String, Object> calInByParkAndRange(int parkId, Date startDate, Date endDate) {
		// TODO Auto-generated method stub
		return chargeDao.calInByParkAndRange(parkId, startDate, endDate);
	}

	@Override
	public Map<String, Object> calInByParkAndRangeMoney(Date startDate, Date endDate) {
		// TODO Auto-generated method stub
		return chargeDao.calInByParkAndRangeMoney(startDate, endDate);
	}

	@Override
	public Map<String, Object> calOutByParkAndRange(int parkId, Date startDate, Date endDate) {
		// TODO Auto-generated method stub
		return chargeDao.calOutByParkAndRange(parkId, startDate, endDate);
	}

	@Override
	public Map<String, Object> calOutByParkAndRangeMoney(Date startDate, Date endDate) {
		// TODO Auto-generated method stub
		return chargeDao.calOutByParkAndRangeMoney(startDate, endDate);
	}

	/*
	 * @Override public int getByDateAndParkCount(int parkId, String startDate,
	 * String endDate) { // TODO Auto-generated method stub return
	 * chargeDao.getByDateAndParkCount(parkId, startDate, endDate); }
	 * 
	 * 
	 * @Override public double getChannelCharge(int parkId, String startDate, String
	 * endDate) { // TODO Auto-generated method stub return
	 * chargeDao.getChannelCharge(parkId, startDate, endDate); }
	 */

	@Override
	public String getByDateAndParkCountzbs(int parkId, String startDate, String endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getByDateAndParkCountzbs(parkId, startDate, endDate);
	}

	@Override
	public String getByDateAndParkCountzje(int parkId, String startDate, String endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getByDateAndParkCountzje(parkId, startDate, endDate);
	}

	@Override
	public String getByDateAndParkCountbs(int parkId, String startDate, String endDate, int payType) {
		// TODO Auto-generated method stub
		return chargeDao.getByDateAndParkCountbs(parkId, startDate, endDate, payType);
	}

	@Override
	public String getByDateAndParkCountje(int parkId, String startDate, String endDate, int payType) {
		// TODO Auto-generated method stub
		return chargeDao.getByDateAndParkCountje(parkId, startDate, endDate, payType);
	}

	@Override
	public void calExpense(PosChargeData charge, Date exitDate, Boolean isQuery) throws Exception {

		Boolean isMonthUser = false;
		Boolean isRealMonthUser = false;
		// Boolean isMonthUserMoreCars=false;
		List<Monthuser> monthusers = monthUserService.getByCarnumberAndPark(charge.getCardNumber(), charge.getParkId());
		Monthuser monthuserUse = new Monthuser();
		for (Monthuser monthuser : monthusers) {
			if (monthuser.getType() == 0) {
				Long diff = (monthuser.getEndtime().getTime() - (new Date()).getTime());
				if (diff > 0) {
					isMonthUser = true;
					monthuserUse = monthuser;
					isRealMonthUser = true;
					break;
				}
			}
		}
		Park park = parkService.getParkById(charge.getParkId());
		Boolean isMultiCarsOneCarport = false;
		if (park.getDescription() != null && park.getDescription().contains("一位多车")) {
			isMultiCarsOneCarport = true;
		}

		if (isMultiCarsOneCarport && monthuserUse.getPlatecolor() != null
				&& monthuserUse.getPlatecolor().equals("包月转临停")) {
			isRealMonthUser = false;
			monthuserUse.setPlatecolor("出场完结");
			monthUserService.updateByPrimaryKeySelective(monthuserUse);
		}

		if (isRealMonthUser) {
			charge.setChargeMoney(0);
			charge.setUnPaidMoney(0);
			charge.setExitDate1(exitDate);
			charge.setPaidCompleted(true);
			charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
			if (!isQuery) {
				if (isMultiCarsOneCarport && monthuserUse.getPlatecolor().equals("多车包月入场")) {
					monthuserUse.setPlatecolor("出场完结");
					List<Monthuser> monthuserss = monthUserService.getByUsernameAndPark(monthuserUse.getOwner(),
							monthuserUse.getParkid());

					monthUserService.updateByPrimaryKeySelective(monthuserUse);
				}
				this.update(charge);
			}
			return;
		}

		Integer criterionId = park.getFeeCriterionId();
		FeeCriterion criterion = criterionService.getById(criterionId);
		// 白天晚上模版
		if (criterion.getType() == 2) {
			newFeeCalcExpense2(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}
		// 按次收费
		if (criterion.getType() == 1) {
			newFeeCalcExpense1(charge, criterion, exitDate, isQuery);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}

		if (criterion.getType() == 4) {// 24小时
			newFeeCalcExpense4(charge, criterion, exitDate, isQuery, park);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}
		// 三个计费阶段
		if (criterion.getType() == 6) {
			newFeeCalcExpense6(charge, criterion, exitDate, isQuery, park);
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}

		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(charge.getEntranceDate());
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "07";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		int isOneTimeExpense = charge.getIsOneTimeExpense();
		if (charge.getIsLargeCar() == false) {
			Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
			for (String name : dates.keySet()) {
				charge.setEntranceDate(name);
				int houra = Integer.parseInt(name.substring(11, 13));
				int hourNight = Integer.parseInt(nightStartHour);
				int hourDay = Integer.parseInt(nightEndHour);
				boolean isNight = false;
				if (houra > 12) {
					if (houra >= hourNight) {
						isNight = true;
					}
				} else {
					if (houra < hourDay) {
						isNight = true;
					}
				}
				if (isNight) {
					charge.setIsOneTimeExpense(1);
					this.calExpenseSmallCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				} else if (isOneTimeExpense == 0) {
					charge.setIsOneTimeExpense(0);
					this.calExpenseSmallCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				} else {
					charge.setIsOneTimeExpense(1);
					this.calExpenseSmallCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				}
			}
			// System.out.println("计费计算后: "+new Date().getTime()+"\n");
			// System.out.println("计费更新前: "+new Date().getTime()+"\n");
			charge.setEntranceDate(startTime);
			charge.setExitDate(endTime);
			if (charge.getPaidMoney() >= charge.getChargeMoney() && !isQuery) {
				charge.setUnPaidMoney(0);
				charge.setPaidCompleted(true);
				charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
				charge.setChangeMoney(charge.getPaidMoney() - charge.getChargeMoney());
			} else {
				charge.setUnPaidMoney(charge.getChargeMoney() - charge.getPaidMoney());
			}
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
			// System.out.println("计费更新后: "+new Date().getTime()+"\n");

		} else {
			Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
			for (String name : dates.keySet()) {
				charge.setEntranceDate(name);
				int houra = Integer.parseInt(name.substring(11, 13));
				int hourNight = Integer.parseInt(nightStartHour);
				int hourDay = Integer.parseInt(nightEndHour);
				boolean isNight = false;
				if (houra > 12) {
					if (houra >= hourNight) {
						isNight = true;
					}
				} else {
					if (houra < hourDay) {
						isNight = true;
					}
				}
				if (isNight) {
					charge.setIsOneTimeExpense(1);
					this.calExpenseLargeCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				} else if (isOneTimeExpense == 0) {
					charge.setIsOneTimeExpense(0);
					this.calExpenseLargeCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				} else {
					charge.setIsOneTimeExpense(1);
					this.calExpenseLargeCar(charge, new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)),
							isQuery);
				}
			}
			charge.setEntranceDate(startTime);
			charge.setExitDate(endTime);
			if (charge.getPaidMoney() >= charge.getChargeMoney() && !isQuery) {
				charge.setUnPaidMoney(0);
				charge.setPaidCompleted(true);
				charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
				charge.setChangeMoney(charge.getPaidMoney() - charge.getChargeMoney());
			} else {
				charge.setUnPaidMoney(charge.getChargeMoney() - charge.getPaidMoney());
			}
			if (isRealMonthUser) {
				// charge.setPaidMoney(0);
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}

		}

	}

	@Override
	public List<Park> getParkByMoney(Map<String, Object> map) {
		// TODO Auto-generated method stub
		return chargeDao.getParkByMoney(map);
	}

	@Override
	public int gongcount() {
		// TODO Auto-generated method stub
		return chargeDao.gongcount();
	}

	// 主平台今日数据统计
	@Override
	public List<Park> getParkByCountMoney(Map<String, Object> map) {
		// TODO Auto-generated method stub
		return chargeDao.getParkByCountMoney(map);
	}

	@Override
	public String getByDateAndParkCountPayzbs(String startDate, String endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getByDateAndParkCountPayzbs(startDate, endDate);
	}

	@Override
	public String getByDateAndParkCountPayzje(String startDate, String endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getByDateAndParkCountPayzje(startDate, endDate);
	}

	@Override
	public String getByDateAndParkCountPayTypebs(String startDate, String endDate, int payType) {
		// TODO Auto-generated method stub
		return chargeDao.getByDateAndParkCountPayTypebs(startDate, endDate, payType);
	}

	@Override
	public String getByDateAndParkCountPayTypeje(String startDate, String endDate, int payType) {
		// TODO Auto-generated method stub
		return chargeDao.getByDateAndParkCountPayTypeje(startDate, endDate, payType);
	}

	@Override
	public List<PosChargeData> getByCarNumberAndPN(String cardNumber, String parkName) {
		// TODO Auto-generated method stub
		return chargeDao.getByCarNumberAndPN(cardNumber, parkName);
	}

	@Override
	public List<PosChargeData> getByCardNumberAndParkName(String cardNumber, String parkName, Integer parkId) {
		// TODO Auto-generated method stub
		return chargeDao.getByCardNumberAndParkName(cardNumber, parkName, parkId);
	}

	@Override
	public List<PosChargeData> getByParkDatetime(String cardNumber, String startDate, String endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getByParkDatetime(cardNumber, startDate, endDate);
	}

	@Override
	public String getByParkpaidMoneyjine(String startDate, String endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getByParkpaidMoneyjine(startDate, endDate);
	}

	@Override
	public String getBypaidMoneyjine(int parkId, String startDate, String endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getBypaidMoneyjine(parkId, startDate, endDate);
	}

	@Override
	public List<PosChargeData> getDebtWithParkId(String cardNumber, Date exitDate, Integer parkId) throws Exception {
		// TODO Auto-generated method stub
		List<PosChargeData> charges = chargeDao.getDebtWithParkId(cardNumber, parkId);
		int i = 0;
		for (PosChargeData charge : charges) {
			if (charge.getExitDate() == null && i < 1) {
				i++;
				Park park = parkService.getParkById(charge.getParkId());
				// System.out.println("park------------:"+park);
				if (park.getType() == 1) {
					this.calExpenseType1(charge, exitDate, false);
				} else {
					this.calExpense(charge, exitDate, false);
				}
			}
			if (charge.getExitDate() == null && i >= 1) {
				// System.out.println("出场时间-----------:"+charge.getExitDate());
				charge.setChargeMoney(0);
				charge.setPaidMoney(0);
				charge.setUnPaidMoney(0);
				charge.setPaidCompleted(true);
				charge.setExitDate1(new Date());
				charge.setOther2("系统清场");
				update(charge);
			}
		}

		return charges;
	}

	// 统计今日数据列表的应收实收
	@Override
	public Map<String, Object> selectPosdataSumByParkAndRangeMoney(int id, String startDay, String endDay) {
		// TODO Auto-generated method stub
		return chargeDao.selectPosdataSumByParkAndRangeMoney(id, startDay, endDay);
	}

	public Date getEntranceDate(PosChargeData charge, FeeCriterion criterion) {
		long newEnter = charge.getEntranceDate().getTime() + criterion.getFreemins() * 60 * 1000;

		if (criterion.getId() == 129) {// 泰州工行计费标准免费半小时
			if (isNight(charge, criterion,
					new SimpleDateFormat(Constants.DATEFORMAT).format(charge.getEntranceDate()))) {
				newEnter = charge.getEntranceDate().getTime() + criterion.getFreemins() * 60 * 1000 / 2;
			}
		}
		if (criterion.getId() == 125) {// 六合路边收费系统免费时长15分钟30秒
			newEnter = charge.getEntranceDate().getTime() + 15 * 60 * 1000 + 30 * 1000;
			if (charge.getCardNumber().length() > 7) {// 新能源车免费时长1小时
				newEnter = charge.getEntranceDate().getTime() + 60 * 60 * 1000;
			}
		}
		Date enterTime = new Date(newEnter);
		return enterTime;
	}

	public boolean isNight(PosChargeData charge, FeeCriterion criterion, String enterDate) {
		if (criterion.getNightstarttime() == null || criterion.getNightendtime() == null) {
			return false;
		}
		int houra = Integer.parseInt(enterDate.substring(11, 13));

		int hourNight = Integer.parseInt(criterion.getNightstarttime().split(":")[0]);
		int hourDay = Integer.parseInt(criterion.getNightendtime().split(":")[0]);
		boolean isNight = false;
		if (houra > 12) {
			if (houra >= hourNight) {
				isNight = true;
			}
		} else {
			if (houra < hourDay) {
				isNight = true;
			}
		}
		return isNight;
	}

	public void calFeeSmallCarWithData(PosChargeData charge, Date exitDate, Boolean isQuery, Park park,
			FeeCriterion criterion) throws ParseException {
		logger.info(charge.getCardNumber() + "进入小车计费免费时段许提前剔除");
		charge.setExitDate1(exitDate);
		double expense = 0;
		if (criterion.getIsonetimeexpense() != null && criterion.getIsonetimeexpense().intValue() == 1) {
			charge.setIsOneTimeExpense(1);
		}
		float diffMin = (float) Math
				.ceil((charge.getExitDate().getTime() - charge.getEntranceDate().getTime()) / (1000 * 60f));
		if (charge.getIsOneTimeExpense() == 1) {
			expense = criterion.getOnetimeexpense();
			if (criterion.getId() > 29) {
				expense = criterion.getStep3price();
			}
			logger.info(charge.getCardNumber() + "夜间计费" + expense);
		} else {
			float firstHour = criterion.getStep1capacity();
			if (diffMin <= firstHour) {
				double intervals = Math.ceil(diffMin / (float) criterion.getTimeoutpriceinterval());
				expense = intervals * criterion.getStep1price();
				logger.info(charge.getCardNumber() + "第一阶段计费" + expense);
			} else {
				double intervals1 = Math.ceil(firstHour / (float) criterion.getTimeoutpriceinterval());
				expense = intervals1 * criterion.getStep1price();
				double intervals2 = Math.ceil((diffMin - firstHour) / (float) (criterion.getTimeoutpriceinterval()));
				expense += intervals2 * criterion.getStep2price();
				logger.info(charge.getCardNumber() + "第二阶段计费" + intervals2 * criterion.getStep2price());
			}
		}
		if (expense > criterion.getMaxexpense()) {

			expense = criterion.getMaxexpense();
		}
		double money = 0.0;
		if (charge.getDiscountType() == 1) {
			money = 0;
		} else if (charge.getDiscountType() == 2) {
			money = Double.valueOf(df.format(expense + charge.getChargeMoney())) - charge.getDiscount() > 0
					? Double.valueOf(df.format(expense + charge.getChargeMoney())) - charge.getDiscount()
					: 0;
		} else if (charge.getDiscountType() == 3) {
			money = charge.getDiscount();
		}
		charge.setChargeMoney(Double.valueOf(df.format(expense + charge.getChargeMoney())));
		charge.setPaidMoney(money);
		charge.setPaidCompleted(true);
		charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
		logger.info(charge.getCardNumber() + " "
				+ new SimpleDateFormat(Constants.DATEFORMAT).format(charge.getEntranceDate()) + " "
				+ new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate) + "calExpenseSmallCarWithData费用"
				+ charge.getChargeMoney());
	}

	public void calFeeLargeCarWithData(PosChargeData charge, Date exitDate, Boolean isQuery, Park park,
			FeeCriterion criterion) {
		logger.info(charge.getCardNumber() + "进入大车计费免费时段已提前剔除");
		int rate = 1;
		if (StringUtils.isNotBlank(criterion.getOther())) {
			String ctrOther = criterion.getOther();
			if (ctrOther.contains("MaxRateToSmallCar")) {
				rate = 2;
			}
		}
		if (criterion.getIsonetimeexpense() != null && criterion.getIsonetimeexpense().intValue() == 1) {
			charge.setIsOneTimeExpense(1);
		}
		charge.setExitDate1(exitDate);
		double expense = 0;
		float diffMin = (charge.getExitDate().getTime() - charge.getEntranceDate().getTime()) / (1000 * 60f);
		if (charge.getIsOneTimeExpense() == 1) {
			expense = criterion.getOnetimeexpense();
			if (criterion.getId() > 29) {
				expense = criterion.getStep3price();
			}
			logger.info(charge.getCardNumber() + "夜间计费" + expense);
		} else {
			float firstHour = criterion.getStep1capacity();

			if (diffMin <= firstHour) {
				double intervals = Math.ceil(diffMin / (float) criterion.getTimeoutpriceinterval());
				expense = intervals * criterion.getStep1pricelarge();
				logger.info(charge.getCardNumber() + "第一阶段计费" + expense);
			} else {
				double intervals1 = Math.ceil(firstHour / (float) criterion.getTimeoutpriceinterval());
				expense = intervals1 * criterion.getStep1pricelarge();
				double intervals2 = Math.ceil((diffMin - firstHour) / (float) (criterion.getTimeoutpriceinterval()));
				expense += intervals2 * criterion.getStep2pricelarge();
				logger.info(charge.getCardNumber() + "第二阶段计费" + intervals2 * criterion.getStep2price());
			}

		}
		if (expense > criterion.getMaxexpense() * rate) {
			expense = criterion.getMaxexpense() * rate;
			logger.info(charge.getCardNumber() + "超过最高计费,费用修正为" + expense);
		}
		charge.setChargeMoney(Double.valueOf(df.format(expense + charge.getChargeMoney())));
		logger.info(charge.getCardNumber() + " "
				+ new SimpleDateFormat(Constants.DATEFORMAT).format(charge.getEntranceDate()) + " "
				+ new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate) + "calExpenseLargeCarWithData费用"
				+ charge.getChargeMoney());
	}

	public void calCommonPark(PosChargeData charge, Date exitDate, Boolean isQuery, Boolean isRealMonthUser, Park park,
			FeeCriterion criterion) throws ParseException {
		Date tmpentranceDate = charge.getEntranceDate();
		Date dateTime1 = getEntranceDate(charge, criterion);
		if (dateTime1.getTime() >= exitDate.getTime()) {
			logger.info(charge.getCardNumber() + "在免费时段内" + Utility.formatDatetime(dateTime1) + "-"
					+ Utility.formatDatetime(exitDate));
			charge.setChargeMoney(0);
			charge.setUnPaidMoney(0);
			charge.setExitDate1(new Date());
			charge.setPaidCompleted(true);
			charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
			charge.setOther2("免费时段");
			if (!isQuery) {
				this.update(charge);
			}
			return;
		}

		String startTime = new SimpleDateFormat(Constants.DATEFORMAT).format(dateTime1);
		String endTime = new SimpleDateFormat(Constants.DATEFORMAT).format(exitDate);
		String nightStartHour = "20";
		String nightEndHour = "07";
		if (criterion.getNightstarttime() != null && criterion.getNightendtime() != null) {
			nightStartHour = criterion.getNightstarttime().split(":")[0];
			nightEndHour = criterion.getNightendtime().split(":")[0];
		}
		int isOneTimeExpense = charge.getIsOneTimeExpense();
		if (charge.getIsLargeCar() == false) {
			Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
			for (String name : dates.keySet()) {
				charge.setEntranceDate(name);

				if (isNight(charge, criterion, name)) {
					charge.setIsOneTimeExpense(1);
					this.calFeeSmallCarWithData(charge,
							new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)), isQuery, park,
							criterion);
				} else if (isOneTimeExpense == 0) {
					charge.setIsOneTimeExpense(0);
					this.calFeeSmallCarWithData(charge,
							new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)), isQuery, park,
							criterion);
				} else {
					charge.setIsOneTimeExpense(1);
					this.calFeeSmallCarWithData(charge,
							new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)), isQuery, park,
							criterion);
				}
			}
			charge.setEntranceDate1(tmpentranceDate);
			charge.setExitDate(endTime);
			if (charge.getPaidMoney() >= charge.getChargeMoney() && !isQuery) {
				charge.setUnPaidMoney(0);
				charge.setPaidCompleted(true);
				charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
				charge.setChangeMoney(charge.getPaidMoney() - charge.getChargeMoney());
			} else {
				charge.setUnPaidMoney(charge.getChargeMoney() - charge.getPaidMoney());
			}
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}
		} else {
			Map<String, String> dates = formatTime.format(startTime, endTime, nightStartHour, nightEndHour);
			for (String name : dates.keySet()) {
				charge.setEntranceDate(name);

				if (isNight(charge, criterion, name)) {
					charge.setIsOneTimeExpense(1);
					this.calFeeLargeCarWithData(charge,
							new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)), isQuery, park,
							criterion);
				} else if (isOneTimeExpense == 0) {
					charge.setIsOneTimeExpense(0);
					this.calFeeLargeCarWithData(charge,
							new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)), isQuery, park,
							criterion);
				} else {
					charge.setIsOneTimeExpense(1);
					this.calFeeLargeCarWithData(charge,
							new SimpleDateFormat(Constants.DATEFORMAT).parse(dates.get(name)), isQuery, park,
							criterion);
				}
			}
			charge.setEntranceDate1(tmpentranceDate);
			charge.setExitDate(endTime);
			if (charge.getPaidMoney() >= charge.getChargeMoney() && !isQuery) {
				charge.setUnPaidMoney(0);
				charge.setPaidCompleted(true);
				charge.setPayTime(new SimpleDateFormat(Constants.DATEFORMAT).format(new Date()));
				charge.setChangeMoney(charge.getPaidMoney() - charge.getChargeMoney());
			} else {
				charge.setUnPaidMoney(charge.getChargeMoney() - charge.getPaidMoney());
			}
			if (isRealMonthUser) {
				charge.setChargeMoney(0);
				charge.setUnPaidMoney(0);
			}
			if (!isQuery) {
				this.update(charge);
			}

		}
	}

	@Override
	public List<PosChargeData> getUnpaidChargeData(int parkId, Date startDate, Date endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getUnpaidChargeData(parkId, startDate, endDate);
	}

	@Override
	public List<PosChargeData> getReviewList(int parkId, double other, Date startDate, Date endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getReviewList(parkId, other, startDate, endDate);
	}

	@Override
	public PosChargeData getByParkIdAndCardNumberAndDate(int parkId, String cardNumber, Date date) {
		// TODO Auto-generated method stub
		return chargeDao.getByParkIdAndCardNumberAndDate(parkId, cardNumber, date);
	}

	@Override
	public List<PosChargeData> getAllByDayRangeV1(int parkId, String pastDay, String nowDay) {
		// TODO Auto-generated method stub
		return chargeDao.getAllByDayRangeV1(parkId, pastDay, nowDay);
	}

	@Override
	public List<PosChargeData> getByCardNumberAndParkV1(String plateNumber, int parkId) {
		// TODO Auto-generated method stub
		return chargeDao.getByCardNumberAndParkV1(plateNumber, parkId);
	}

	@Override
	public int updateByParkIdAndPlateNumber(int parkId, String plateNumber, int couponType, Double couponMoney,
			String distributor) {
		// TODO Auto-generated method stub
		return chargeDao.updateByParkIdAndPlateNumber(parkId, plateNumber, couponType, couponMoney, distributor);
	}

	@Override
	public PosChargeData selectPosChargeDataByYestDay(Date yestStartDay, Date yestEndDay) {
		// TODO Auto-generated method stub
		return chargeDao.selectPosChargeDataByYestDay(yestStartDay, yestEndDay);
	}

	@Override
	public ParkRecordData getByIdV1(int poschargeId) {
		// TODO Auto-generated method stub
		return chargeDao.getByIdV1(poschargeId);
	}

	@Override
	public int updatePicture(int id, String inUrl, String outUrl) {
		// TODO Auto-generated method stub
		return chargeDao.updatePicture(id, inUrl, outUrl);
	}

	@Override
	public int updateById(int id, String format) {
		// TODO Auto-generated method stub
		logger.info("修改posChargeId" + id + "的计费时间为:" + format);
		return chargeDao.updateById(id, format);
	}

	@Override
	public List<PosChargeData> getByParkIdAndCardNumberV2(int parkId, String cardNumber) {
		// TODO Auto-generated method stub
		return chargeDao.getByParkIdAndCardNumberV2(parkId, cardNumber);
	}

	@Override
	public int updateByInvoice(int parkId, String cardNumber) {
		// TODO Auto-generated method stub
		return chargeDao.updateByInvoice(parkId, cardNumber);
	}

	@Override
	public List<PosChargeData> getList(int parkId, String cardNumber, String startDate, String endDate, int i,
			int pageSize) {
		// TODO Auto-generated method stub
		return chargeDao.getList(parkId, cardNumber, startDate, endDate, i, pageSize);
	}

	@Override
	public int getListAllCount(int parkId, String cardNumber, String startDate, String endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getListAllCount(parkId, cardNumber, startDate, endDate);
	}

	@Override
	public List<Park> getParkByCardNumber(String cardNumber, String startDate, String endDate) {
		// TODO Auto-generated method stub
		return chargeDao.getParkByCardNumber(cardNumber, startDate, endDate);
	}

}
